Сопоставление регулярных выражений для слов без дефиса - Python

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

Требования к регулярному выражению:

  1. Он не должен содержать дефисов И
  2. Он должен содержать как минимум 1 цифру

Я пробовал следующие выражения: =

^(?!.*-)

  • Это соответствует всем словам без дефиса, но я не могу понять, как дополнительно добавить второе условие.

^(?!.*-(?=/d{1,}))

  • Я пробовал использовать двойной просмотр вперед, но не уверен в синтаксисе, который нужно использовать. Это соответствует ID101, но также соответствует STACKOVERFLOW

Примеры слов, которые должны соответствовать: 1DRIVE, ID100, W1RELESS

Примеры слов, которые не должны совпадать: в основном любая нечисловая строка (например, СТЕК, ПЕРЕПОЛНЕНИЕ) или любые слова с переносом (Тест-11, 24 часа)

Дополнительная информация:

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

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


person Interested_Programmer    schedule 15.11.2019    source источник
comment
Это поиск нескольких в одной строке или проверка ввода одного слова?   -  person ctwheels    schedule 15.11.2019
comment
Вам подходит это?   -  person Toto    schedule 15.11.2019
comment
@ctwheels Он выполняет поиск по одному слову после того, как я токенизировал ввод и удалил слова шума.   -  person Interested_Programmer    schedule 15.11.2019
comment
Все решения Тото, Пола и Эммы отлично подходят для моих требований! Я мог выбрать только один ответ. Спасибо вам всем троим!   -  person Interested_Programmer    schedule 15.11.2019


Ответы (2)


Может быть,

(?!.*-)(?=.*\d)^.+$

может просто работать нормально.

Контрольная работа

import re

string = '''
abc
abc1-
abc1
abc-abc1
'''

expression = r'(?m)(?!.*-)(?=.*\d)^.+$'


print(re.findall(expression, string))

Вывод

['abc1']

Если вы хотите упростить / изменить / изучить выражение, это объясняется на верхней правой панели regex101. com. При желании вы также можете посмотреть по этой ссылке, как она будет соответствовать против некоторых исходных образцов.


Цепь RegEx

jex.im визуализирует обычный выражения:

введите описание изображения здесь

RegEx 101 Объяснение

/
(?!.*-)(?=.*\d)^.+$
/
gm

Negative Lookahead (?!.*-)
Assert that the Regex below does not match
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
- matches the character - literally (case sensitive)
Positive Lookahead (?=.*\d)
Assert that the Regex below matches
.* matches any character (except for line terminators)
* Quantifier — Matches between zero and unlimited times, as many times as possible, giving back as needed (greedy)
\d matches a digit (equal to [0-9])
^ asserts position at start of a line
.+ matches any character (except for line terminators)
+ Quantifier — Matches between one and unlimited times, as many times as possible, giving back as needed (greedy)
$ asserts position at the end of a line
Global pattern flags
g modifier: global. All matches (don't return after first match)
m modifier: multi line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)
person Emma    schedule 15.11.2019
comment
не могли бы вы это объяснить? - person Interested_Programmer; 15.11.2019
comment
Спасибо! Это помогает. - person Interested_Programmer; 15.11.2019

Я придумал -

^[^-]*\d[^-]*$

  1. поэтому нам нужна как минимум одна цифра (\d)
  2. Нам нужно, чтобы остальная часть строки содержала что-нибудь, НО a - ([^-])
  3. У нас может быть неограниченное количество этих символов, поэтому [^-]*
  4. но объединение их вместе, как [^-]*\d, не удастся на aaa3-, потому что - появляется после действительного совпадения - позволяет убедиться, что никакие тире не могут проскользнуть до или после нашего совпадения ^[-]*\d$
  5. К сожалению, это означает, что aaa555D не работает. Таким образом, нам действительно нужно снова добавить первую группу - ^[^-]*\d[^-]$ --- в которой указано начало - любое количество символов, которые не являются тире - цифра - любое количество символов, которые не являются тире - конец

  6. В зависимости от стиля мы также можем использовать ^([^-]*\d)+$, поскольку порядок цифр / чисел не имеет значения, мы можем иметь их столько, сколько захотим.

Однако, наконец ... вот как я бы ДЕЙСТВИТЕЛЬНО решил эту конкретную проблему, поскольку регулярные выражения могут быть мощными, но они имеют тенденцию усложнять код для понимания ...

if ("-" not in text) and re.search("\d", text):

person Paul Becotte    schedule 15.11.2019