C # регулярное выражение соответствует только части полных слов в строке - PullRequest
1 голос
/ 04 мая 2009

Перед тем, как задавать этот вопрос, я нашел эту проблему в Google и просмотрел все вопросы, связанные со StackOverflow.

Проблема довольно проста

У меня есть строка "Организация Североатлантического договора"

У меня есть шаблон "a. * Z", в данный момент он будет соответствовать

Северная АТЛАТИЧЕСКАЯ ДОГОВОРНАЯ ОРГАНИЗАЦИЯ

Но мне нужно, чтобы он совпадал только с полными словами (например, для ОРГАНИЗАЦИИ)

Я пробовал "\ ba z \ b" и "\ Ba z \ B" как образец, но я думаю, что не совсем понял

Как мне изменить шаблон, чтобы соответствовать полному слову, содержащемуся в строке (без совпадения с несколькими словами)

Шаблоны генерируются на лету, пользователь вводит * z, и мое приложение переводит его в шаблон, который соответствует частям полных слов в строке.

Моя проблема в том, что я не знаю, что пользователь будет искать. В идеале я бы добавил к выражению пользователя некоторое регулярное выражение.

Спасибо!

Ответы [ 5 ]

4 голосов
/ 04 мая 2009

ANIZ в организации - это , а не полное слово - это часть слова. Кстати, ваш шаблон не тот, что вы написали - a*z не будет соответствовать, как вы описываете; вы, вероятно, вместо этого используете a.*z, что будет. Итак, попробуйте a[^ ]*z, чтобы он не совпадал с пробелами. Если есть другие символы, кроме пробелов, которые вы не хотите сопоставлять, например, некоторые знаки препинания, конечно же, вставьте их в конструкцию [^...].

3 голосов
/ 04 мая 2009
"a[^\s]*z"

Это означает «a», за которым следует любое количество непробельных символов, после которых следует «z».

РЕДАКТИРОВАТЬ: Вы, кажется, хотите, чтобы '*' интерпретировался как символ подстановки. Таким образом, пользователь должен вводить не регулярное выражение, а строку с определенными подстановочными знаками. Вы можете перевести эти символы подстановки в регулярные выражения, рассуждая о предполагаемом значении. Допустим, что «*» должно означать «ноль или более символов, которые не являются пробелами». Затем вы заменяете этот символ на соответствующее регулярное выражение:

                       [^\s]*
                       `-.-´|
     Character class-----´  `---Zero or more of these

     '\s': "Whitespace"
     Inside Character class: if it starts with '^': "not"

Вы также можете определить '?' как совпадающие точно с одним непробельным символом. Это тот же класс символов, но в конце вы опускаете '*'.

Итак, вы выполняете регулярное выражение - замените "*" на "[^\s]*" и "?" на "[^\s]".

1 голос
/ 06 мая 2009
Regex reWord = new Regex("\\b[A-Za-z]*?(a.*z)[A-Za-z]*\\b");

... это вернет "Организацию Атлантического Договора", а захват из. * z будет "Организацией против Договора".

Проблема присуща вашему методу - если вы не проанализируете предоставленное пользователем «регулярное выражение» для * z (или. * z, что не совсем понятно из вашего поста), изменив * на [ ^ \ S] *? как предлагает Сванте (или, может быть, \ w *?), вы сожрете гораздо больше символов, чем вам нравится.

". *" - это вообще плохая идея, когда вы пытаетесь быть конкретным. Это будет соответствовать всему, кроме новой строки, и вы ничего не можете добавить к этому, что остановит это.

Regex reWord = new Regex("\\b\\w*?(a\\w*?z)\\w*\\b");

... вернется просто "Организация".

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

В конечном счете, это ГИГО - мусор входит, мусор выходит. Накормите свою систему плохим регулярным выражением, и если вы не исправите это должным образом, вы не получите то, что искали.

1 голос
/ 04 мая 2009

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

Такой инструмент очень помогает найти правильный шаблон, который может быть довольно сложным. Хороший инструмент для .net RegEx - RegExLab , немного старше, но хорошо показывает, что именно соответствует вашему регулярному выражению. Поскольку страница на немецком языке, просто нажмите на ссылку regexlab.006.zip. Исходный код также включен.

1 голос
/ 04 мая 2009

это то, что вы ищете:

new Regex( @"\b[^ ]*a[^ ]*z[^ ]*\b" );

соответствует только одному слову (без пробелов) - но целому. Вы можете перевести свои пользовательские входные данные в такое регулярное выражение - просто замените * на [^] * - он работает даже с несколькими подстановочными знаками.

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