首先,我尝试了您使用Expresso提供的表达式,然后在LinqPad中尝试了- 两者都返回了整个字符串,这不是您想要匹配的。我看到 2 个问题,为什么它没有显示预期的结果:
- 正则表达式本身
- 示例字符串中的问题(标签不是成对的,即每个标签都
<pre>
必须由 关闭</pre>
)
除此之外,我建议对代码进行一些改进:
- 更改匹配方式(下面的示例使用正则表达式选项,并允许分组)
- 添加 tagName 作为参数,添加参数以允许包含或排除标签
- 返回集合而不是计数值
看一下代码,它运行良好(我为LinqPad添加了一些可选的、注释掉的.Dump()
语句,以防您想打印出用于调试的值):
Public Function FindCode(input As String, tagName as string, includeTags as boolean)
Const grpName as string = "pregroup"
Dim pattern As String = "(<"+tagName+">)(?<"+grpName+">(\s|\w|')+)(</"+tagName+">)"
Dim output As New Dictionary(Of Integer, String)
Dim count As Integer
Dim options as RegexOptions = RegexOptions.IgnoreCase _
or RegexOptions.IgnorePatternWhitespace _
or RegexOptions.MultiLine or RegexOptions.ExplicitCapture
' options.Dump("options")
Dim rx as Regex = new Regex(pattern, options)
For Each m As Match In rx.Matches(input)
Dim val as string=nothing
if (includeTags)
val = m.Value
else
if(m.Groups(grpName).Success)
val = m.Groups(grpName).Value
end if
end if
if not (val is nothing)
' val.Dump("Found #" & count+1)
output.Add(count, val)
count += 1
end if
Next
Return output
End Function
关于表达:
- 我使用
(\s|\w)+
而不是.+
,因为它只包含空格和字母数字字符,而不是括号,因此不包含标签
- 通过使用(其中 nn 是字符的十六进制代码)转义与正则表达式语法的特殊字符冲突
\xnn
的字符 - 注意:这在这里不适用
- 使用组名轻松访问标签的内容
关于Regex
代码:我添加了参数includeTags
,以便您可以看到差异(false
不包括它们,true
包括它们)。请注意,您应该始终正确设置 RegexOptions,因为它会影响表达式的匹配方式。
最后,这是主要代码:
Sub Main
dim input as string = "Some random markup <pre> and this stuff in the middle is what I'm after </pre> and there <pre> lots of these in one file </pre> which when I use Regexhero <pre> finds all the tags </pre>"
dim result = FindCode(input, "pre", false)
dim count as integer = result.Count()
Console.WriteLine(string.Format("Found string {0} times.", count))
Console.WriteLine("Findings:")
for each s in result
Console.WriteLine(string.format("'{0}'", s.Value))
next
End Sub
这将输出:
找到字符串 2 次。
发现:
'很多这些在一个文件中'
' 找到所有标签 '
但是,还有一个问题:为什么第一个不<pre>...</pre>
匹配?看一下子字符串I'm after
- 它包含'
不匹配的内容,因为它既不是空格也不是字母数字。您可以通过在正则表达式中指定来添加它(\s|\w|')
,然后它将显示所有 3 个字符串。