我正在尝试将Match Whole Word搜索添加到我的小应用程序中。 我希望它能像Visual Studio一样做。 例如,下面的代码应该可以正常工作:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
String input = "[ abc() *abc ]";
Match(input, "abc", 2);
Match(input, "abc()", 1);
Match(input, "*abc", 1);
Match(input, "*abc ", 1);
}
private void Match(String input, String pattern, int expected)
{
String escapedPattern = Regex.Escape(pattern);
MatchCollection mc = Regex.Matches(input, @"\b" + escapedPattern + @"\b", RegexOptions.IgnoreCase);
if (mc.Count != expected)
{
throw new Exception("match whole word isn't working");
}
}
}
搜索“abc”工作正常但其他模式返回0结果。 我认为\ b不合适,但我不确定该使用什么。
任何帮助将不胜感激。 感谢
答案 0 :(得分:4)
\b
元字符匹配字母数字字符和非字母数字字符之间的字边界。由于\b
按预期工作,以非字母数字字符结尾的字符串最终无法匹配。
执行适当的全字匹配,支持您需要的两种类型的数据:
\b
\B
(大写B
)\B
,例如带有尾随空格的最终示例基于这些要点,您需要有额外的逻辑来检查传入的搜索词,以将其塑造成适当的模式。 \B
的工作方式与\b
相反。如果您不使用\B
,则可能会错误地以部分匹配结束。例如,单词foo*abc
将错误地与@"\*abc\b"
的模式匹配。
演示:
string input = "[ abc() *abc foo*abc ]";
string[] patterns =
{
@"\babc\b", // 3
@"\babc\(\)\B", // 1
@"\B\*abc\b", // 1, \B prefix ensures whole word match, "foo*abc" not matched
@"\*abc\b", // 2, no \B prefix so it matches "foo*abc"
@"\B\*abc " // 1
};
foreach (var pattern in patterns)
{
Console.WriteLine("Pattern: " + pattern);
var matches = Regex.Matches(input, pattern);
Console.WriteLine("Matches found: " + matches.Count);
foreach (Match match in matches)
{
Console.WriteLine(" " + match.Value);
}
Console.WriteLine();
}
答案 1 :(得分:2)
我认为这就是你要找的东西:
@"(?<!\w)" + escapedPattern + @"(?!\w)"
\b
是根据当前位置之前和之后是否存在“单词”字符来定义的。你只关心之前的第一个角色是什么,之后的是什么。
答案 2 :(得分:0)
\b
是零宽度断言,匹配单词字符和非单词字符。
字母,数字和下划线是单词字符。 *
,SPACE和parens是非单词字符。因此,当您使用\b*abc\b
作为模式时,它与您的输入不匹配,因为*是非单词。同样适用于涉及parens的模式。
要解决这个问题,
在输入(非转义)模式以非单词字符开头或结尾的情况下,您需要消除\b
。
public void Run()
{
String input = "[ abc() *abc ]";
Match(input, @"\babc\b", 2);
Match(input, @"\babc\(\)", 1);
Match(input, @"\*abc\b", 1);
Match(input, @"\*abc\b ", 1);
}
private void Match(String input, String pattern, int expected)
{
MatchCollection mc = Regex.Matches(input, pattern, RegexOptions.IgnoreCase);
Console.WriteLine((mc.Count == expected)? "PASS ({0}=={1})" : "FAIL ({0}!={1})",
mc.Count, expected);
}