2013-03-25 2 views
3

Нам не удается создать регулярное выражение для соответствия всем именам файлов, содержащим 888, за исключением тех, которые содержат 888/444, 888/447 или 888/405.Регулярное выражение для сопоставления всех имен файлов с 888, кроме тех, которые содержат 888/444, 888/447 или 888/405?

Мы пробовали использовать классы символов и отрицали их, но они, похоже, не работали. Совет?

Вот что мы пробовали: /888.[^(444)|(447)|(405)]/

Мы используем Руби 1.9.3. Благодаря!

+0

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

ответ

2
[^a-z] 

Соответствует символу, который не находится в диапазоне a-z. В вашей попытке вы добавили группу чередования внутри класса символов, но она просто не работает. Вместо этого, вы должны использовать отрицательное lookaround утверждение (предполагая, рубин поддерживает эти):

/^888(?!(44[47]|405)).*$/ 

Чтобы разорвать этот вниз:

^   # Anchor to start of string 
888   # Match 888 
(?!   # Negative lookahead 
    (  # Alternation group 
    44[47] # Match 444 or 447 
    |  # ...or... 
    405  # 405 
) 
) 
.*   # Match any number of any characters 
$   # Anchor to end of string 

Обратите внимание, что та часть, которая говорит: «Матч любое количество любых символов» будут ограничены негативным прогнозом, так что 444, 447 и 405 будут соответствовать , а не, согласно вашим требованиям.

Таким образом, это будет соответствовать 888123, 888 foo bar, но не позволит 888444 или 888447 и т.д.


EDIT Чтобы соответствовать требованию появляться в любом месте в пределах строки:

/888(?!.*4(4[47]|05)).*/ 

т. Е. Соответствует любому 888, за которым следует что-либо (включая ничего), кроме 444, 447 или 405.

+0

Это нормально, если вы соответствуете началу строки – Xophmeister

+0

Достаточно справедливо: похоже, этот комментарий появился во время написания моего ответа: P – Xophmeister

+0

Ваше редактирование не будет соответствовать '888', например. ' "888hello444"'. – MikeM

3

Используйте отрицательный предпросмотр:

888.(?!(444)|(447)|(405)) 
+1

Не нужно использовать внутренний '()'. – MikeM

+1

Это будет соответствовать '888/444.888.'например – pguardiario

0

Если у вас есть что-то очень конкретное в виду, как то, что у вас есть в настоящее время, почему бы не совпадать с обратным, а затем отфильтровать элементы, которые соответствуют?

Как так:

/(888\/444)|(888\/447)|(888\/405)/ 

, который соответствует тем, что вы не хотите использовать это и устранить соответственно.

2

Я собираюсь пойти с:

/^(?!.*888\/(444|447|405)).*888.*/ 

Я не верю, что есть более простой способ сделать это.

Смежные вопросы