【问题标题】:RegEx pattern in .VB.VB 中的正则表达式模式
【发布时间】:2010-09-16 19:16:08
【问题描述】:

我有一个字符串,需要一个正则表达式模式,所以我只能从标签中提取日期和数字:

Dim a as string= "<table id=table-1 > <tbody> <td align=right> <h2 id=date-one>12.09.2010</h2> </td> </tr> </tbody></table> <table id=table-2 border=0 cellspacing=0 cellpadding=0><tbody><tr><td align=center valign=middle><h3 id=nb-a>01</h3></td><td align=center valign=middle><h3 id=nb-a>>02</h3></td><td align=center valign=middle><h3 id=nb-a>03</h3></td></tr></tbody></table>"

这个字符串会有不止一个相似的数据块...所以我必须在循环中... 谢谢! 阿德里安

【问题讨论】:

标签: .net regex visual-studio


【解决方案1】:

只是构建了 jball 发布的示例。我只是觉得这样比关注后向正则表达式或前向正则表达式更容易。 在这里,我使用括号来利用 Match.Groups。

m.Groups(0).Value = ">xxxxxx

m.Groups(1).Value = ">"

m.Groups(2).Value = "xxxxxx"

m.Groups(3).Value = "

   Dim input As String = "<table id=table-1 > <tbody> <td align=right> <h2 id=date-one>12.09.2010</h2> </td> </tr> </tbody></table> <table id=table-2 border=0 cellspacing=0 cellpadding=0><tbody><tr><td align=center valign=middle><h3 id=nb-a>01</h3></td><td align=center valign=middle><h3 id=nb-a>>02</h3></td><td align=center valign=middle><h3 id=nb-a>03</h3></td></tr></tbody></table>"

        Dim regex1 As Regex = New Regex("(>)([\d.]+)(<)")
        Dim matches As MatchCollection = regex1.Matches(input)

        For Each m As Match In matches
            Console.WriteLine(String.Format("{1}{0}", m.Groups(2).Value, Environment.NewLine))
        Next

【讨论】:

    【解决方案2】:

    从长远来看,html 解析器(例如 HtmlAgilityPack)会更简单,但作为 Regex 的指南,以下是针对您的情况的方法:

      Dim pattern As String = "" 'what goes here?
      ' wrapping line for viewing, 
      ' imagine the following is a single line
      Dim a As String = 
         "<table id=table-1 > <tbody> <td align=right> 
         <h2 id=date-one>12.09.2010</h2> </td> </tr> </tbody></table> 
         <table id=table-2 border=0 cellspacing=0 cellpadding=0>
         <tbody><tr><td align=center valign=middle><h3 id=nb-a>01
         </h3></td><td align=center valign=middle><h3 id=nb-a>>02
         </h3></td><td align=center valign=middle><h3 id=nb-a>03</h3>
         </td></tr></tbody></table>"
      ' end of the a variable declaration
      For Each match As Match In Regex.Matches(a, pattern)
         Console.WriteLine("Found '{0}' at position {1}", match.Value, match.Index)
      Next
    

    天真地第一次尝试匹配任何数字:

    Dim pattern As String = "[\d]+"    ' \d matches any number,
                                       ' + specifies one or more
    

    这当然匹配了太多的项目,并且不匹配作为单个组的日期。在您的情况下,每个匹配项都在一个标签内,因此前面有一个“>”,后面是一个“

    Dim pattern As String = ">[.\d]+<" ' allow the '.' as well as numbers
                                       ' capture any string that starts with '>'
                                       ' followed by one or more numbers and '.'
                                       ' ending with '<'
    

    不幸的是,这在您的匹配项中包含了“>”和“

    Dim pattern As String = "(?<=>)[.\d]+(?=<)" 
                                       ' (?<=regex) is positive lookbehind for regex
                                       ' (?=regex) is positive lookahead for regex
                                       ' capture any string after '>' 
                                       ' with by one or more numbers and '.'
                                       ' before '<'
    

    现在情况看起来不错,因为我们只匹配日期和三个数字!但是,如果日期用“-”或“/”而不是“.”分隔怎么办?

    Dim pattern As String = "(?<=>)[-/.\d]+(?=<)" 
                                       ' add '-' and '/' to date separators
    

    容易处理。但是如果元素文本中的数字或日期前后有空格怎么办?

    Dim pattern As String = "(?<=>\s*)[-/.\d]+(?=\s*<)"
                                       ' lookbehind regex is ">\s*" means match
                                       '    the char '>' 
                                       '    followed by 0 or more whitespace chars
                                       ' lookahead regex is "\s*<" means match
                                       '    0 or more whitespace chars
                                       '    followed by the char '<' 
    

    还不错。唯一的问题是,与使用 html 解析器循环遍历所有元素、检查元素文本是否为有效数字或日期并将匹配的元素文本添加到列表中相比,此方法仍然需要更多的努力和更容易中断。

    例如,考虑更改 Regex 方法以处理货币(其中“$100.03.45”不应匹配)或数字中的逗号,或确保日期恰好有三组,每组有一位、两位或四位数字,其中只有一位组可以有四个,两个数字组中的一个不能超过 12 等等。精神错乱就在那条路上。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 2017-03-25
      • 1970-01-01
      相关资源
      最近更新 更多