从长远来看,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 等等。精神错乱就在那条路上。