比如说我有以下字符串"one two(three) (three) four five"
,我希望将"(three)"
替换为"(four)"
,但不能替换为单词。我该怎么做?
基本上我想做一个正则表达式替换并最终得到以下字符串:
"one two(three) (four) four five"
我尝试了以下正则表达式,但它不起作用:
@"\b\(three\)\b"
基本上我正在编写一些搜索和替换代码,并给用户提供匹配大小写,匹配整个单词等的常用选项。在这种情况下,用户选择匹配整个单词但我不知道文本是什么搜索将是。
答案 0 :(得分:53)
你的问题源于对\b
实际意味着什么的误解。不可否认,这并不明显。
\b\(three\)\b
与输入字符串中的三个字符不匹配的原因如下:
\b
表示:单词字符与非单词字符之间的边界。(
等标点符号被视为非单词字符。这是你的输入字符串,稍微延伸一点,我已经标记了\b
匹配的地方:
o n e t w o ( t h r e e ) ( t h r e e ) f o u r f i v e
↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
正如你在这里看到的,“两个”和“(三个)”之间有一个\b
,但不是在第二个“(三个)”之前。
故事的寓意?如果您要搜索的内容不仅仅是一个单词(一串字母),那么“全字搜索”并没有多大意义。由于搜索字符串中有标点符号(括号),因此它不是“单词”。如果您搜索的单词只包含单词字符,那么\b
就可以达到预期效果。
当然,只有当字符串被空格包围或出现在字符串的开头或结尾时,您才可以使用不同的正则表达式来匹配字符串:
(^|\s)\(three\)(\s|$)
然而,问题当然是,如果你搜索“三”(没有括号),它将找不到“(三)”中的那个,因为它周围没有空格,即使它实际上是一个完整的词。
我认为只有当您的搜索字符串实际开始和/或以单词字符结尾时,大多数文本编辑器(包括Visual Studio)才会使用\b
:
var pattern = Regex.Escape(searchString);
if (Regex.IsMatch(searchString, @"^\w"))
pattern = @"\b" + pattern;
if (Regex.IsMatch(searchString, @"\w$"))
pattern = pattern + @"\b";
即使你选择“仅限整个单词”,他们也会找到“(三)”。
答案 1 :(得分:4)
这是您可能感兴趣的简单代码:
string pattern = @"\b" + find + @"\b";
Regex.Replace(stringToSearch, pattern, replace, RegexOptions.IgnoreCase);
答案 2 :(得分:0)
我最近在javascript中发现了一个类似的问题,试图将条款与前导'$'字符匹配为单独的字词,例如if $ hot ='FUZZ',然后:
"some $hot $hotel bird$hot pellets" ---> "some FUZZ $hotel bird$hot pellets"
正则表达式/\b\$hot\b/g
(我的第一次猜测)不起作用的原因与parens在原始问题中不匹配 - 作为非单词字符,在它们之前没有单词/非单词边界与空格或字符串开始。
然而,正则表达式/\B\$hot\b/g
匹配,这表明在@ timwi的优秀示例中标记的位置不与\ B term匹配。这对我来说并不直观,因为") ("
不是由正则表达式字符组成的。但我猜是因为\ B是\ b类的反转,它不一定是单词字符,它只是必须是不是字的字符:)
答案 3 :(得分:-1)
正如Gopi所说,但(理论上)仅捕获(three)
而不是two(three)
:
string input = "one two(three) (three) four five";
string output = input.Replace(" (three) ", " (four) ");
当我测试时,我得到:"one two(three) (four) four five"
请记住,空格也是一个字符串字符,所以它也可以被替换。如果我这样做了:
//use same input
string output = input.Replace(" ", ";");
我会得到one;two(three);(three);four;five"