2016-02-15 7 views
0

У меня есть регулярное выражение для захвата фраз, которые являются взаимоисключающими группами из двух слов (каждое слово в строке будет записано не более одного раза). Я пытаюсь исключить определенную (переменную) фразу из захваченных групп. Регулярное выражение /\w+\s+\w+/, предоставленное @Casimir, будет разделять строку, сопоставляя группы по желанию, но нам также необходимо исключить группу, которая может встречаться где угодно в строке, и может возникать несколько раз.Захват фраз, за ​​исключением переменной фразы

Для строки

'next saturday, swing dancing at the kato ballroom! bring friends!' 

и фразы 'swing dancing' регулярное выражение должно возвращать каждую группу вернулся ниже, за исключением «крыла танцы».

Тестовые:

"next saturday, swing dancing at the kato ballroom! bring friends!". 
    scan(/((?!swing dancing)(?:\w+)\s(?!swing dancing)(?:\w+))/) 
=> [["next saturday"], ["wing dancing"], ["at the"], ["kato ballroom"], ["bring friends"]] 

ссылка http://rubular.com/r/Eogo29Ociz

"next saturday, swing dancing at the kato ballroom! come dancing with friends!" 
    .scan(/((?!dancing)(?:\w+)\s(?!dancing)(?:\w+))/) 
=> [["next saturday"], ["ancing at"], ["the kato"], ["ancing with"]] 

ссылка http://rubular.com/r/1TpcveiuX0

Это должно вернуть

[["next saturday"], ["at the"], ["kato ballroom"], ["with friends"]] 

Регулярный expre ssion может не понадобиться повторять негативный взгляд, если мы согласны с фразами по обе стороны фразы, чтобы исключить.

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

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

ответ

3

Используйте захват группы выделить цель и поставить строку, которую вы не хотите, прежде чем в необязательном не-захвата группы: /\b(?:swing\s+dancing\W+)?(\w+\s+\w+)/

> "next saturday, swing dancing at the kato ballroom! bring friends!".scan(/\b(?:swing\s+dancing\W+)?(\w+\s+\w+)/) 
=> [["next saturday"], ["at the"], ["kato ballroom"], ["bring friends"]] 

demo rubular

или с \K функции: /\b(?:swing\s+dancing\W+)?\K\w+\s+\w+/

> "next saturday, swing dancing at the kato ballroom! bring friends!".scan(/\b(?:swing\s+dancing\W+)?\K\w+\s+\w+/) 
=> ["next saturday", "at the", "kato ballroom", "bring friends"] 

Два способа аналогичны. Они не стараются избегать «качающихся танцев», напротив, они пытаются найти его в первую очередь. Тогда последняя задача состоит в том, чтобы исключить ее из результата.

Первая модель использует захват группы (так как метод сканирования возвращает только группы захвата если таковые имеются), а второй шаблон использует \Kсказать «ничего не возвращает до этого момента».

+0

Ницца! Что нам нужно сделать, чтобы сделать эту работу, исключая «танцы»? – bjorn

+0

@bjorn: для этого вам нужно прочитать мой ответ и понять его. –

+0

Проблема заключается в том, что '\ b (?: Dancing \ W +)? (\ W + \ s + \ w +) \ b' по-прежнему соответствует фразе« swing dancing ». – bjorn

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