Извлечение точных слов или набора символов с помощью регулярных выражений в Python - PullRequest
2 голосов
/ 28 апреля 2020

Предположим, у меня есть такой список.

List = ['MX_QW-765', 'RUC_PO-345', 'RUC_POLO-209']. 

Я хочу найти и вернуть совпадение, в котором есть 'PO'. Технически я должен иметь RUC_PO-345 в качестве вывода, но даже RUC_POLO-209 возвращается как вывод вместе с RUC_PO-345.

Ответы [ 6 ]

2 голосов
/ 28 апреля 2020

До обновления вопрос:

Согласно моему комментарию, я думаю, что вы используете неправильный подход. Мне кажется, вы можете просто использовать in:

words = ['cat', 'caterpillar', 'monkey', 'monk', 'doggy', 'doggo', 'dog']
if 'cat' in words:
    print("yes")
else:
    print("no")

Возвращает: yes

words = ['cats', 'caterpillar', 'monkey', 'monk', 'doggy', 'doggo', 'dog']
if 'cat' in words:
    print("yes")
else:
    print("no")

Возвращает: no


После обновленного вопроса:

Теперь, если ваши примеры данных не соответствуют вашим потребностям, но вы заинтересованы в поиске подстроки в элементе списка, вы можете попробовать:

import re
words = ['MX_QW-765', 'RUC_PO-345', 'RUC_POLO-209']
srch = 'PO'
r = re.compile(fr'(?<=_){srch}(?=-)')
print(list(filter(r.findall, words)))

Или используя match:

import re
words = ['MX_QW-765', 'RUC_PO-345', 'RUC_POLO-209']
srch = 'PO'
r = re.compile(fr'^.*(?<=_){srch}(?=-).*$')
print(list(filter(r.match, words)))

Это вернет список элементов (в данном случае просто ['RUC_PO-345']), которые следуют шаблону. Я использовал приведенный выше обычный шаблон, чтобы убедиться, что значение вашего поиска не будет находиться в начале строки поиска, но будет после подчеркивания и сопровождается -.


Теперь, если у вас есть список продуктов, которые вы хотите найти, рассмотрите ниже:

import re
words = ['MX_QW-765', 'RUC_PO-345', 'RUC_POLO-209']
srch = ['PO', 'QW']
r = re.compile(fr'(?<=_)({"|".join(srch)})(?=-)')
print(list(filter(r.findall, words)))

Или снова используйте match:

import re
words = ['MX_QW-765', 'RUC_PO-345', 'RUC_POLO-209']
srch = ['PO', 'QW']
r = re.compile(fr'^.*(?<=_)({"|".join(srch)})(?=-).*$')
print(list(filter(r.match, words)))

Оба вернутся: ['MX_QW-765', 'RUC_PO-345']

Обратите внимание, что если у вас не поддерживаются f-строки, вы также можете добавить свою переменную в шаблон.

1 голос
/ 28 апреля 2020

Шаблон:

‘_PO[^\w]’

должен работать с вызовом re.search () или re.findall (); он не будет работать с re.match, так как он не учитывает символы в начале строки.

Шаблон гласит: match 1 подчеркивание ('_'), за которым следует 1 заглавная P ('P') , за которой следует 1 заглавная O ('O'), за которой следует один символ, который не является символом слова . Специальный символ '\ w' соответствует [a-zA-Z0-9_].

‘_PO\W’

^ Это также может быть использовано в качестве более короткой версии для первого предложенного шаблона (credit @JvdV в комментариях)

‘_PO[^A-Za-z]’

В этом паттерне используется «Набор символов, а не букв». В случае, если da sh мешает любому из первых двух шаблонов.

Чтобы использовать это для идентификации шаблона в списке, вы можете использовать al oop:

import re

For thing in my_list:
    if re.search(‘_PO[^\w]’, thing) is not None:
        # do something
        print(thing)

Это будет использовать вызов re.search для сопоставления с шаблоном в качестве условия True в условном выражении if. Когда re не соответствует строке, возвращается None; следовательно синтаксис ... if re.search() is not None.

Надеюсь, это поможет!

1 голос
/ 28 апреля 2020

Вам необходимо добавить знак $, обозначающий конец строки, вы также можете добавить ^, который является началом строки, поэтому только cat соответствует:

 ^cat$
1 голос
/ 28 апреля 2020

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

words = ['cat', 'caterpillar', 'monkey', 'monk', 'doggy', 'doggo', 'dog']
your_text = 'I like cat, dog, rabbit, antelope, and monkey, but not giraffes'
regex = r'\b(?:' + '|'.join(words) + r')\b'
print(regex)
matches = re.findall(regex, your_text)
print(matches)

Это напечатает:

\b(?:cat|caterpillar|monkey|monk|doggy|doggo|dog)\b
['cat', 'dog', 'monkey']

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

0 голосов
/ 28 апреля 2020

Вы должны использовать регулярное выражение (import re) , и вы должны использовать это регулярное выражение: r'(?<![A-Za-z0-9])PO(?![A-Za-z0-9])'.

Я ранее рекомендовал \b особая последовательность, но оказывается, что '_' считается частью слова, и это не так для вас, поэтому это не сработает.

Это оставляет вас с несколько более сложным отрицательным взгляд назад и отрицательные утверждения, которые есть то, чем являются (?<! ... и (?! ..., соответственно. Чтобы понять, как они работают, прочитайте документацию по Python регулярным выражениям.

0 голосов
/ 28 апреля 2020

Мы можем попытаться сопоставить одно из трех точных слов 'cat', 'dog', 'monk' в нашей строке регулярного выражения.

Наша строка регулярного выражения будет "\b(?:cat|dog|monk)\b"

\b используется для определения границы слова. Мы используем \b, чтобы мы могли искать целые слова (это именно та проблема, с которой вы столкнулись). Добавление этого будет не соответствовать tomcat или caterpillar и только cat

Далее (?:) называется группой без захвата (Объяснено здесь )

Теперь нам нужно сопоставить одно из cat или dog или monk. Так что это выражается как cat|dog|monk. В python 3 это будет:

import re

words = ['cat', 'caterpillar', 'monkey', 'monk', 'doggy', 'doggo', 'dog']
regex = r"\b(?:cat|dog|monk)\b"

r=re.compile(regex)
matched = list(filter(r.match, words))

print(matched)

Чтобы реализовать регулярное выражение через итеративный список, мы используем функцию filter, как указано в ответе Stackoverflow здесь

Вы можете найти исполняемый код Python здесь

ПРИМЕЧАНИЕ: Наконец, regex101 - это отличный онлайн-инструмент для опробования различных строк регулярных выражений и получения их объяснений. в реальном времени. Объяснение для нашей строки регулярного выражения: здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...