регулярное выражение две группы соответствует всему, пока шаблон - PullRequest
0 голосов
/ 08 мая 2018

У меня есть следующие примеры:

Tortillas Bolsa 2a 1kg 4118
Tortillinas 50p 1 31Kg TAB TR 46113
Bollos BK 4in 36p 1635g SL 131
Super Pan Bco Ajonjoli 680g SP WON 100  
Pan Blanco Bimbo Rendidor 567g BIM 49973
Gansito ME 5p 250g MTA MLA 49860

Где я хочу сохранить все до числа, но я также не хочу, чтобы пример состоял из двух заглавных букв: ME, BK. Я использую ^((\D*).*?) [^A-Z]{2,3}

Ожидаемый результат должен быть

Tortillas Bolsa
Tortillinas
Bollos
Super Pan Bco Ajonjoli
Pan Blanco Bimbo Rendidor
Gansito

Используя регулярное выражение, которое я использую, я все еще получаю два заглавных слова Bollos BK и Gansito ME

Ответы [ 5 ]

0 голосов
/ 08 мая 2018

Мои 2 цента

^.*?(?=\s[\d]|\s[A-Z]{2,})

https://regex101.com/r/7xD7DS/1/

0 голосов
/ 08 мая 2018

Я предлагаю разделить первые две заглавные буквы на слово или цифру и взять первый элемент:

r = re.compile(r'\b[A-Z]{2}\b|\d')
[r.split(item)[0].strip() for item in my_list]
# => ['Tortillas Bolsa', 'Tortillinas', 'Bollos', 'Super Pan Bco Ajonjoli', 'Pan Blanco Bimbo Rendidor', 'Gansito']

См. Демоверсию Python

Детали шаблона

  • \b[A-Z]{2}\b - целое (так как \b - границы слов) два заглавных слова ASCII
  • | - или
  • \d - цифра.

При .strip() все завершающие и ведущие пробелы будут обрезаны.

Небольшое отклонение для re.sub:

re.sub(r'\s*(?:\b[A-Z]{2}\b|\d).*', '', s)

См. Демоверсию regex

Детали

  • \s* - 0+ пробельных символов
  • (?:\b[A-Z]{2}\b|\d) - либо слово из двух заглавных букв, либо цифра
  • .* - остаток строки.
0 голосов
/ 08 мая 2018

Предварительно скомпилируйте шаблон регулярного выражения с предвидением (объяснено ниже) и используйте regex.match в понимании списка:

>>> import re
>>> p = re.compile(r'\D+?(?=\s*([A-Z]{2})?\s*\d)')
>>> [p.match(x).group() for x in data]

[
 'Tortillas Bolsa',
 'Tortillinas',
 'Bollos',
 'Super Pan Bco Ajonjoli',
 'Pan Blanco Bimbo Rendidor',
 'Gansito'
]

Здесь data - ваш список строк.

Подробности

\D+?            # anything that isn't a digit (non-greedy)
(?=             # regex-lookahead
\s*             # zero or more wsp chars
([A-Z]{2})?     # two optional uppercase letters
\s*   
\d              # digit
)

В случае, если какая-либо строка не содержит искомый шаблон, понимание списка будет ошибочным (с AttributeError), поскольку re.match возвращает None в этом случае. Затем вы можете использовать цикл и проверить значение re.match перед извлечением соответствующей части.

matches = []
for x in data:
    m = p.match(x)
    if m:
        matches.append(m.group())

Или, если вы хотите заполнитель None, когда нет совпадений:

matches = []
for x in data:
    matches.append(m.group() if m else None)
0 голосов
/ 08 мая 2018

Предположим, что:

  • Все слова, которые вы хотите найти в вашей группе захвата, начинаются с заглавной буквы
  • Остальная часть каждого слова содержит только строчные буквы
  • Слова разделяются одним пробелом

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

  1. Использование Свойства символов Unicode :

    ^((\p{Lu}\p{Ll}+ )+)
    

    > Попробуйте это регулярное выражение на регулярном выражении 101.

  2. Без поддержки Unicode:

    ^(([A-z][a-z]+ )+)
    

    > Попробуйте это регулярное выражение для regex101.

0 голосов
/ 08 мая 2018

Вы можете использовать функцию просмотра:

I_WANT        = '(.+?)' # This is what you want
I_DO_NOT_WANT = '\s(?:[0-9]|(?:[A-Z]{2,3}\s))' # Stop-patterns
RE = '{}(?={})'.format(I_WANT, I_DO_NOT_WANT) # Combine the parts

[re.findall(RE, x)[0] for x in test_strings]
#['Tortillas Bolsa', 'Tortillinas', 'Bollos', 'Super Pan Bco Ajonjoli',
# 'Pan Blanco Bimbo Rendidor', 'Gansito']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...