WedX - журнал о программировании и компьютерных науках

Regex для ограничения слов с определенной комбинацией букв (в любом порядке)

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

Я хочу, чтобы регулярное выражение искало любые слова с помощью:

e 0 или 1 раз
a 0 или 1 раз
t 0 или 1 или 2 раза

Например, будет работать следующее:

eat tea tate tt a e

Следующее не сработает

eats teas tates ttt aa ee

Lookaround Regex является новым для меня, поэтому я не уверен на 100% в синтаксисе (любой ответ, использующий lookaround с объяснением, был бы потрясающим). Мое лучшее предположение на данный момент:

Regex regex = new Regex(@"(?=.*e)(?=.*a)(?=.*t)");
lines = lines.Where(x => regex.IsMatch(x)).ToArray(); //'text' is array containing words
21.11.2015

  • Я не думаю, что регулярное выражение может делать то, что вы хотите (пожалуйста, поправьте меня, если я ошибаюсь!). Возможно, вы могли бы разделить текст на слова, а затем подсчитать количество символов, встречающихся в каждом слове? Затем, если сумма подсчетов, которые вы сделали, не равна длине слова, это должно означать, что вокруг плавают дополнительные недопустимые символы. 21.11.2015
  • Это возможность. Я думаю, что регулярное выражение может обрабатывать что-то подобное... однако я тоже могу ошибаться. 21.11.2015

Ответы:


1

Конечно:

\b(?:e(?!\w*e)|t(?!(?:\w*t){2})|a(?!\w*a))+\b

Пояснение:

\b             # Start of word
(?:            # Start of group: Either match...
 e             # an "e",
 (?!\w*e)      # unless another e follows within the same word,
|              # or
 t             # a "t",
 (?!           # unless...
  (?:\w*t){2}  # two more t's follow within the same word,
 )             # 
|              # or
 a             # an "a"
 (?!\w*a)      # unless another a follows within the same word.
)+             # Repeat as needed (at least one letter)
\b             # until we reach the end of the word.

Протестируйте его на сайте regex101.com.

(Для простоты я использовал класс символов \w; если вы хотите по-другому определить разрешенные «словные символы», замените его соответствующим образом)

21.11.2015
  • Вот и все, не так ли :D или с небольшими изменениями @NealR. 21.11.2015
  • Слова OP на самом деле являются string[]. Таким образом, вам нужно заботиться не о сопоставлении слов, а о целых строках. 21.11.2015
  • Единственная проблема с регулярным выражением Тима заключается в том, что он использовал * вместо +, что позволяло ему сопоставлять пустые строки. (Видите эти вертикальные линии вокруг всех других слов в демонстрации? Которые я обновил, кстати) Границы слов работают так же хорошо, как и якоря, потому что допустимые слова всегда полностью состоят из букв. 21.11.2015
  • По какой-то причине это почти работает, но не совсем. Например - didn't doesn't и don't дозваниваются. Это из-за апострофа? 22.11.2015
  • @bobblebubble — ваше регулярное выражение работает. Единственная разница, которую я замечаю, это ? символ перед каждой буквой в группе... однако, опять же, я мог что-то упустить. Пример: (?!.*?e) против (?!\w*e) 22.11.2015
  • @NealR: Да, \w соответствует буквам, цифрам и знаку подчеркивания - как я уже сказал, это упрощение. Вы можете создать класс символов, содержащий разрешенные символы, например [A-Za-z'] или (если вы хотите разрешить не-ASCII буквы) [\p{L}'] и т. д. вместо \w. Единственное требование, предъявляемое регулярным выражением, состоит в том, что каждое слово должно начинаться и заканчиваться реальной буквой. В противном случае привязки границ слов не будут работать правильно. 22.11.2015

  • 2

    Это, вероятно, то же самое, что и другие, я не форматировал их, чтобы узнать.

    Обратите внимание, что утверждения принудительно сопоставляются, они не могут быть необязательными
    (если специально не установлены необязательными, но зачем?) и не затрагиваются прямым откатом.

    Это работает, объяснение находится в отформатированном регулярном выражении.

    обновлено
    Чтобы использовать границу пробела, используйте это:

    (?<!\S)(?!\w*(?:e\w*){2})(?!\w*(?:a\w*){2})(?!\w*(?:t\w*){3})[eat]+(?!\S)

    Отформатировано:

     (?<! \S )
     (?!
          \w* 
          (?: e \w* ){2}
     )
     (?!
          \w* 
          (?: a \w* ){2}
     )
     (?!
          \w* 
          (?: t \w* ){3}
     )
     [eat]+ 
     (?! \S )
    

    Чтобы использовать обычную границу слова, используйте это:

    \b(?!\w*(?:e\w*){2})(?!\w*(?:a\w*){2})(?!\w*(?:t\w*){3})[eat]+\b

    Отформатировано:

     \b                     # Word boundary
     (?!                    # Lookahead, assert Not 2 'e' s
          \w* 
          (?: e \w* ){2}
     )
     (?!                    #  Lookahead, assert Not 2 'a' s
          \w* 
          (?: a \w* ){2}
     )
     (?!                    #  Lookahead, assert Not 3 't' s
          \w* 
          (?: t \w* ){3}
     )
     # At this point all the checks pass, 
     # all thats left is to match the letters.
     # -------------------------------------------------
    
     [eat]+                 # 1 or more of these, Consume letters 'e' 'a' or 't'
     \b                     # Word boundary
    
    21.11.2015
  • Я получаю тот же результат, что и приведенное ниже регулярное выражение — слова вроде didn't doesn't и don't проходят (хотя это фильтрует то же количество слов, что и другой ответ). Опять же, расширяя границы моих знаний о регулярных выражениях, но может ли это быть из-за апострофа? 22.11.2015
  • @NealR - также добавлена ​​граница пробела. Это должно предотвратить совпадение этих do's и don't. 22.11.2015
  • Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]