Ваша проблема связана с неправильным пониманием того, что на самом деле означает \b
.По общему признанию, это не очевидно.
Причина, по которой \b\(three\)\b
не соответствует тройкам в вашей входной строке, заключается в следующем:
\b
означает: граница между символ слова и несловой символ . - Буквы (например, az) считаются символами слова .
- Знаки пунктуациитакие метки, как
(
считаются несловыми символами .
Здесь снова введена ваша входная строка, немного растянутая, и я отметил места, где \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";
Таким образом, они найдут «(три)», даже если вы выберете «только целые слова».