Regex за исключением отдельных слов - PullRequest
6 голосов
/ 01 декабря 2009

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

applejuice (match)
yummyjuice (match)
yummy-apple-juice (match)
orangeapplejuice (match)
orange-apple-juice (match)
apple-orange-aple (match)
juice-juice-juice (match)
orange-juice (match)

apple (should not match)
orange (should not match)
juice (should not match)

Ответы [ 5 ]

9 голосов
/ 01 декабря 2009

Если вы действительно хотите сделать это с одним регулярным выражением, вы можете найти обходные пути полезными (особенно негативные в этом примере). Регулярное выражение, написанное для Ruby (некоторые реализации имеют разный синтаксис для обходных путей):

rx = /^(?!apple$|orange$|juice$)/
3 голосов
/ 01 декабря 2009

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

Итак - давайте создадим набор символов, которые будут считаться «границами»:

/[^-a-z0-9A-Z_]/        // Will match any character that is <NOT> - _ or 
                        // between a-z 0-9 A-Z 

/(?:^|[^-a-z0-9A-Z_])/  // Matches the beginning of the string, or one of those 
                        // non-word characters.

/(?:[^-a-z0-9A-Z_]|$)/  // Matches a non-word or the end of string

/(?:^|[^-a-z0-9A-Z_])(apple|orange|juice)(?:[^-a-z0-9A-Z_]|$)/ 
   // This should >match< apple/orange/juice ONLY when not preceded/followed by another
   // 'non-word' character just negate the result of the test to obtain your desired
   // result.

В большинстве разновидностей регулярных выражений \b считается «границей слова», но стандартный список «словосочетаний» не включает -, поэтому вам нужно создать пользовательский.Он может совпадать с /\b(apple|orange|juice)\b/, если вы также не пытались поймать - ...

Если вы тестируете только тесты с "одним словом", вы можете пойти с гораздо более простым:

/^(apple|orange|juice)$/ // and take the negation of this...
0 голосов
/ 01 декабря 2009
\A(?!apple\Z|juice\Z|orange\Z).*\Z

будет соответствовать всей строке, если только она не состоит из одного из запрещенных слов.

В качестве альтернативы, если вы не используете Ruby, или вы уверены, что ваши строки не содержат разрывов строк, или вы установили опцию, что ^ и $ не совпадают в начале / конце строк

^(?!apple$|juice$|orange$).*$

тоже будет работать.

0 голосов
/ 01 декабря 2009

Это немного помогает:

((?:apple|orange|juice)\S)|(\S(?:apple|orange|juice))|(\S(?:apple|orange|juice)\S)
0 голосов
/ 01 декабря 2009

Что-то вроде (PHP)

$input = "The orange apple gave juice";
if(preg_match("your regex for validating") && !preg_match("/apple|orange|juice/", $input))
{
  // it's ok;
}
else
{
  //throw validation error
}
...