.VB中的RegEx模式

时间:2010-09-16 19:16:09

标签: .net regex visual-studio

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

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>"

这个字符串将包含多个相似数据块......所以我必须处于循环中...... 谢谢! 阿德里安

2 个答案:

答案 0 :(得分:2)

刚刚建立jball发布的示例。我觉得这样做比关注后面的正则表达式或前瞻性正则表达式更容易。 在这里,我使用括号来利用Match.Groups。

m.Groups(0).Value =“&gt; xxxxxx&lt;”

m.Groups(1).Value =“&gt;”

m.Groups(2).Value =“xxxxxx”

m.Groups(3).Value =“&lt;”

   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

答案 1 :(得分:1)

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

这当然会匹配太多项目,并且不会将日期与单个组匹配。在你的情况下,每个匹配都在一个标签内,因此前面是'&gt;'然后是'&lt;'。

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 '<'

这不幸地包括'&gt;'和'&lt;'在你的比赛中。现在我们需要积极的外观和积极的前瞻:

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个等。疯狂就在这条路上。