首页 > 代码 > 常规代码 > 正文

代码

阅读排行

判断字符串是否匹配通配符
2014-08-05 14:55:37   来源:Fcode研讨团队   评论:0 点击:

此代码可获得某字符串是否可匹配某通配符,支持任意多,任意位置的 ? 和 * 通配符。其中前者代表一个字符,后者代表任意个字符。

此代码可获得某字符串是否可匹配某通配符,支持任意多,任意位置的 ? 和 * 通配符。其中前者代表一个字符,后者代表任意个字符。
\
代码如下,将输出所有 string 数组是否分别匹配 pattern 数组。
Logical Function match_wild(pattern, string)
! compare given string for match to pattern which may
! contain wildcard characters:
! "?" matching any one character, and
! "*" matching any zero or more characters.
! Both strings may have trailing spaces which are ignored.
! Authors: Clive Page, userid: cgp  domain: le.ac.uk, 2003 (original code)
!          Rolf Sander, 2005 (bug fixes and pattern preprocessing)
! Minor bug fixed by Clive Page, 2005 Nov 29, bad comment fixed 2005 Dec 2.
  Implicit None
  Character (Len=*), Intent (In) :: pattern ! pattern may contain * and ?
  Character (Len=*), Intent (In) :: string ! string to be compared
  Integer :: lenp, lenp2, lens, n, p2, p, s
  Integer :: n_question, n_asterisk

  Character (Len=len(pattern)) :: pattern2

  lens = len_trim(string)
  lenp = len_trim(pattern)

! If the pattern is empty, always return true
  If (lenp==0) Then
    match_wild = .True.
    Return
  End If

! The pattern must be preprocessed. All consecutive occurences of
! one or more question marks ('?') and asterisks ('*') are sorted and
! compressed. The result is stored in pattern2.

  pattern2(:) = ''
  p = 1 ! current position in pattern
  p2 = 1 ! current position in pattern2
  Do
    If ((pattern(p:p)=='?') .Or. (pattern(p:p)=='*')) Then
! a special character was found in the pattern
      n_question = 0
      n_asterisk = 0
      Do While (p<=lenp)
! count the consecutive question marks and asterisks
        If ((pattern(p:p)/='?') .And. (pattern(p:p)/='*')) Exit
        If (pattern(p:p)=='?') n_question = n_question + 1
        If (pattern(p:p)=='*') n_asterisk = n_asterisk + 1
        p = p + 1
      End Do
      If (n_question>0) Then ! first, all the question marks
        pattern2(p2:p2+n_question-1) = repeat('?', n_question)
        p2 = p2 + n_question
      End If
      If (n_asterisk>0) Then ! next, the asterisk (only one!)
        pattern2(p2:p2) = '*'
        p2 = p2 + 1
      End If
    Else
! just a normal character
      pattern2(p2:p2) = pattern(p:p)
      p2 = p2 + 1
      p = p + 1
    End If
    If (p>lenp) Exit
  End Do
!!   lenp2 = p2 - 1
  lenp2 = len_trim(pattern2)

! The modified wildcard in pattern2 is compared to the string:

  p2 = 1
  s = 1
  match_wild = .False.
  Do
    If (pattern2(p2:p2)=='?') Then
! accept any char in string
      p2 = p2 + 1
      s = s + 1
    Else If (pattern2(p2:p2)=='*') Then
      p2 = p2 + 1
      If (p2>lenp2) Then
! anything goes in rest of string
        match_wild = .True.
        Exit ! .TRUE.
      Else
! search string for char at p2
        n = index(string(s:), pattern2(p2:p2))
        If (n==0) Exit ! .FALSE.
        s = n + s - 1
      End If
    Else If (pattern2(p2:p2)==string(s:s)) Then
! single char match
      p2 = p2 + 1
      s = s + 1
    Else
! non-match
      Exit ! .FALSE.
    End If
    If (p2>lenp2 .And. s>lens) Then
! end of both pattern2 and string
      match_wild = .True.
      Exit ! .TRUE.
    End If

!! IF (s > lens .AND. (pattern2(p2:p2) == "*") .AND. p2 == lenp2) THEN
!! above line buggy since p2 can be beyond end of string pattern2 by this point. CGP

    If (s>lens .And. p2==lenp) Then
      If (pattern2(p2:p2)=='*') Then
! "*" at end of pattern2 represents an empty string
        match_wild = .True.
        Exit
      End If
    End If
    If (p2>lenp2 .Or. s>lens) Then
! end of either pattern2 or string
      Exit ! .FALSE.
    End If
  End Do

End Function match_wild

Program www_fcode_cn
  Implicit None
  Integer, Parameter :: np = 20, ns = 5
  Character :: pattern(np)*8, string(ns)*12
  Integer :: s, p
  Logical :: match_wild
  External match_wild

  string = (/ 'a.f90       ', 'a1.f90      ', 'a12.f90     ', 'a.f         ', &
    'fcode.cn    ' /)
  pattern = (/ 'a*.f90  ', 'a?*.f90 ', 'a*?.f90 ', 'a?*?.f90', 'a*.f90  ', &
    'a***.f  ', 'a*?*?*? ', 'a**b**c*', 'a*?*b???', '???     ', '*       ', &
    '?       ', '        ', '**?**   ', '?*      ', '*?*     ', '*.f90   ', &
    '*?      ', 'a*??.f90', '?????   ' /)

  Write (*, '(t17, 100a9)') string
  Do p = 1, np
    Write (*, '(a, 100L9)') pattern(p), (match_wild(pattern(p),string(s)), s=1 &
      , ns)
  End Do

End Program www_fcode_cn

相关热词搜索:通配符 字符串 匹配

上一篇:任意大小数组平均成任意大小数组
下一篇:坐标轴刻度自适应算法

分享到: 收藏