2015-07-10 6 views
4

С учетом строки "A B C a b B" Я хочу совместить слова, которые повторяются (независимо от случая). Ожидаемый результат будет соответствующий «а» и «б» (последние вхождения А и В) или «A» и «B» (первые вхождения)Регулярные выражения положительный lookbehind + negative lookahead

EDIT: Я хочу, чтобы соответствовать только первый или последний появление слова

Я знаю, что на этот вопрос можно было бы лучше ответить, разделив строку и подсчитав каждый токен (опустив этот случай).
Тем не менее, я хотел бы попытаться сформулировать регулярное выражение, чтобы помочь мне найти эти слова, только ради практики.

Мой первый выход был: (?=\b(\w+)\b.*\b(\1)\b)(\1)
Однако он совпадает с первым A, первым B и вторым b (A B b).

Я думал, чтобы каким-то образом использовать положительный взгляд-за негативной заглядывая вперёд, чтобы принести последние экземпляры повторяющегося слова: (?<=.*(?!.*(\w+).*)\1.*)\b\1\b
(В моей голове это переводится как «слово, которое было подкреплено до и выиграл» t match again ")

Ну, это не работает для меня, к сожалению.

Можно ли использовать позитивный внешний вид и негативный взгляд вперед?
Может ли мое регулярное выражение быть исправлено?
Я попытался решить эту проблему на C#.

Это не домашнее задание

ответ

1

Интересная головоломка. Вот мое решение:

(\b\w+\b)(?:(?=.*?\b\1\b)|(?<=\b\1\b.*?\1)) 

Demo

Рассуждение выглядит следующим образом:

  • Match слово: (\b\w+\b)

  • Тогда либо: (?: ... | ... )

    • Убедитесь, что происходит позже на: (?=.*?\b\1\b)
    • Или это уже произошло раньше: (?<=\b\1\b.*?\1)

      что в \1 второго назад 'соответствует слову, только согласованное ранее. Первый \1 - настоящий дубликат.


Ответ на отредактированный вопрос:

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

(\b\w+\b)(?=.*?\b\1\b)(?<!\b\1\b.*?\1) 

Demo

Сейчас логика:

  • Match слово: (\b\w+\b)
  • Убедитесь, что она возникает снова: (?=.*?\b\1\b)
  • И убедитесь, что это не произошло раньше: (?<!\b\1\b.*?\1)

    (то же самое, чем до за исключением с отрицательным lookbehind)

+0

Я хочу совместить повторяющиеся слова только один раз. Я редактировал вопрос. Сожалею. –

+0

@nocgod нет проблем, я расширил ответ –

+0

@Lucas_Trezsniewski Отлично! Я перемещал эти части вокруг, понятия не имею, почему я не пробовал простое решение! –