RegEx To Match «целое слово» возвращает исключение - PullRequest
2 голосов
/ 20 июля 2010

Я пытаюсь выполнить проверку через RegEx следующим образом ...

If Regex.IsMatch(Output, "\b" & "Serial)" & "\b") Then
'do something
end if

, но я получаю это исключение аргумента

parsing "\bSerial)\b" - Too many )'s.

Я понимаю ошибку, но как мне изменитьвыражение RegEx?

UPDATE. Слово "Serial)" генерируется динамически.Это означает, что по крайней мере для меня я мог бы получить еще одно исключение для другого персонажа.

Ответы [ 5 ]

5 голосов
/ 20 июля 2010

Предполагая, что это VB.Net, вам нужно экранировать ):

If Regex.IsMatch(Output, "\b" & "Serial\)" & "\b") Then
    'do something
End If

В регулярных выражениях .Net круглые скобки являются символами группировки.


Если,как вы говорите, слово 'Serial)' генерируется динамически, вам нужно будет избежать его, прежде чем передать его в механизм RE:

If Regex.IsMatch(Output, "\b" & Regex.Escape("Serial)") & "\b") Then
    'do something
End If

Как еще один ответчикнаписал, это не будет соответствовать "Serial) xyz" (например), так как между ) и пробелом нет \b (\b существует только между \w и \W символами и) и пробел \W).

Возможно, вам придется прибегнуть к уродливому хаку, например:

If Regex.IsMatch(Output, "\s" & Regex.Escape("Serial)") & "\s") _
Or Regex.IsMatch(Output, "\s" & Regex.Escape("Serial)") & "$") _
Or Regex.IsMatch(Output, "^" & Regex.Escape("Serial)") & "\s") _
Or Regex.IsMatch(Output, "^" & Regex.Escape("Serial)") & "$") _
Then
    'do something
End If

Я подумал, что, возможно, вы могли бы сопоставить класс персонажа(^ или $) и \s в соответствии с:

If Regex.IsMatch(Output, "[\s^]" & Regex.Escape("Serial)") & "[\s$]") Then
    'do something
End If

, но это не похоже на работу на основе тестера регулярных выражений здесь , так что вывозможно, придется пойти на уродливую версию взлома или вы можете объединить их в одно регулярное выражение, как в:

var input = "Serial)"
var escaped = Regex.Escape (input)
var regex = "\s" & escaped & "\s|^" & escaped & "$|\s" & escaped & "$|^" & escaped & "\s"
If Regex.IsMatch(Output, regex) Then
    'do something
End If
4 голосов
/ 20 июля 2010

Ответы Паксдиабло и Танаскиуса правильно объясняют, почему ваше регулярное выражение не компилируется.

Но:

Вы должны быть осторожны с регулярным выражением, даже после выхода за скобки: \b соответствует только в границах слова (слово, составленное из символов сочетания клавиш \w - буквы, цифры, и подчеркивание), не после знаков препинания, как в скобках. В вашем случае регулярное выражение не будет совпадать в строке типа foo Serial) bar. будет совпадать с foo Serial)bar, но только потому, что \b соответствует до bar. Аналогично, он не будет соответствовать строке Serial).

Таким образом, простое окружение строки с \b s не всегда будет делать то, что вы, похоже, ожидаете.

Редактировать: Если, согласно вашему комментарию ниже, в следующем списке ...

foo Serial) bar
foo (Serial) bar
foo Serial). bar
foo Serial))))))
foo Serial)

... должны совпадать только первый и пятый, я предполагаю, что правило должно соответствовать целому слову, только если ему предшествует / сопровождается пробелом или началом / концом строки.

В этом случае используйте

If Regex.IsMatch(Output, "(?<=^|\s)" & Regex.Escape("Serial)") & "(?=\s|$)") Then

Однако теперь это больше не будет соответствовать foo в This is foo. или He said "foo". Если вы хотите разрешить это, используйте

If Regex.IsMatch(Output, "(?<=^|\b|\s)" & Regex.Escape("Serial)") & "(?=\s|\b|$)") Then

... но теперь это будет соответствовать второму примеру. Тщательно выбирайте свое оружие:)

(Объяснение: (?<=^|\b|\s) - это положительное утверждение с задним числом, которое соответствует, если возможно сопоставить начало строки, границу слова или символ пробела непосредственно перед текущей позицией, не добавляя ничего к результату сопоставления. . (?=\s|\b|$) - его ожидающий аналог.)

1 голос
/ 20 июля 2010

Вы должны избежать ввода, используя Regex.Escape () :

String input = "Serial)";
If Regex.IsMatch(Output, "\b" & Regex.Escape( input ) & "\b") Then
  'do something
end if
0 голосов
/ 20 июля 2010

Вам нужно выйти за скобки. то есть) с) Итак, последняя строка должна выглядеть так: \ bSerial) \ b

Если содержимое генерируется динамически, выполните поиск «(» и «)» и замените их соответствующими escape-символами (просто замена строки!) На «(» и «)» или используйте Regex.Escape (), чтобы экранировать эти символов!

НТН

0 голосов
/ 20 июля 2010

Я думаю, что вам может понадобиться

\bSerial\)\b

(это "\ b" & "Serial)" & "\ b")

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...