Я читал эти ответы несколько раз, но НЕ ДЕЙСТВИТЕЛЬНО добирался до тех пор, пока не узнал о техническом определении «Вызов путем совместного использования» , как это называется Барбарой Лисков
Семантика вызова путем совместного использования отличается от вызова по ссылке в том, что назначения для аргументов функции внутри функции не отображаются вызывающему (в отличие от ссылочной семантики) [например, если переменная была передана, невозможно смоделировать присвоение этой переменной в области вызывающего. Однако, поскольку функция имеет доступ к тому же объекту, что и вызывающий (без копирования), мутации для этих объектов, если объекты изменяемы, внутри функции видны вызывающему, которые могут отличаться от вызова по значению семантика. Мутации изменяемого объекта внутри функции видны вызывающему, потому что объект не копируется и не клонируется - он является общим.
То есть, ссылки на параметры изменяются, если вы идете и получаете доступ к самого параметра. С другой стороны, назначение параметра исчезает после оценки и не доступно для вызывающего функции.
Ваша проблема связана с непониманием того, что на самом деле означает \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
будет делать то, что вы ожидаете.
Вы можете, конечно, использовать другое Regex для соответствия строке только если он окружен пробелами или встречается в начале или в конце строки:
(^|\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";
Таким образом, они найдут «(три)», даже если вы выберете только целые слова ».
Как сказал Гопи, но (теоретически) ловить только (three)
not two(three)
:
string input = "one two(three) (three) four five";
string output = input.Replace(" (three) ", " (four) ");
Когда я проверяю это, я получаю: "one two(three) (four) four five"
Просто помните, что белое пространство является string character тоже, поэтому его также можно заменить. Если бы я сделал это:
//use same input
string output = input.Replace(" ", ";");
Я получил бы one;two(three);(three);four;five"
Здесь вам может быть интересен простой код:
string pattern = @"\b" + find + @"\b";
Regex.Replace(stringToSearch, pattern, replace, RegexOptions.IgnoreCase);
Исходный код: snip2code - C #: Заменить точное слово в предложении
Недавно я столкнулся с аналогичной проблемой в 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 термин. Это было неинтуитивно для меня, потому что ") ("
не состоит из символов слова регулярного выражения. Но я предполагаю, что, поскольку \ B является инверсией класса \ b, он не должен быть символами слов, он просто должен быть несловными символами:)
\b
. – tchrist 18 November 2010 в 17:18