Извлеките несколько совпадений после определенной строки или шаблона

#python #regex

Вопрос:

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

у нас есть Новый разговор в 10000 в середине предложения

При использовании регулярного выражения в Python (w ) я получаю вывод ниже

 we 
have 
a 
Newliner 
Chatacter 
in 
10000 
the 
Middle 
of 
the 
sentence
 

Но когда я пытаюсь найти слова между 2 словами с помощью регулярного (?<=a )(w ) выражения , я не получаю желаемого результата.

То, что я получаю, это

 Newliner 
 

Когда я использовал регулярное (?<=a ).* выражение , я получаю остальные слова как одну группу.

И что мне нужно, так это приведенные ниже слова в виде отдельных групп.

 Newliner 
Chatacter 
in 
10000 
the 
Middle 
of 
the 
sentence
 

Комментарии:

1. «Но когда я пытаюсь найти слова между 2 словами», какие 2 слова?

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

Ответ №1:

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

 inp = "we have a Newliner Chatacter in 10000 the Middle of the sentence"
words = re.sub(r'^.*babs ', '', inp).split()
print(words)
 

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

 ['Newliner', 'Chatacter', 'in', '10000', 'the', 'Middle', 'of', 'the', 'sentence']
 

Ответ №2:

TLDR:

  1. С помощью Python re вам нужно выполнить два шага: а) получить местоположение, с которого вы хотите начать сопоставление, а затем использовать Pattern.findall / Pattern.finditer для получения всех ожидаемых совпадений (см. Первые два фрагмента ниже).
  2. С regex помощью модуля PyPI вы можете извлечь эти совпадения одним движением, используя G шаблон регулярного выражения на основе.

re путь

Получение нескольких совпадений после определенного текста является обычным вопросом регулярного выражения, но Python re не может сделать это без дополнительных шагов. То есть вам нужно сначала найти позицию, с которой нужно начать извлечение совпадений, а затем передать эту позицию Pattern.findall() методу (обратите внимание, что это не может быть re.findall статический метод, так как он не принимает pos аргумент).

Для выполнения первого шага вы можете использовать либо регулярное выражение (если вам нужно начать сопоставление с первого/последнего/n-го вхождения некоторого шаблона), либо простой жестко закодированный/буквенный строковый подход (либо с нарезкой, либо с использованием str.find() и т. Д.).

Здесь, похоже, вам нужно начать извлекать совпадения после целого слова a . В этом случае вы можете использовать подход, основанный на регулярных выражениях:

 import re

def extract_all_after_pattern(search_after_rx, reg, text):
    search_after = re.search(search_after_rx, text)
    if search_after:
        # print(f"Found at {search_after.start()}, searching from {len(search_after.group())}, i.e. in '{text[search_after.end() 1:]}'")
        # Found at 8, searching from 1, i.e. in 'Newliner Chatacter in 10000 the Middle of the sentence'
        return reg.findall(text, search_after.end() 1)
    else:
        return []
    
text = "we have a Newliner Chatacter in 10000 the Middle of the sentence"
search_after_rx = r'bab' # Or, r'as', r'sas', r'(?<!S)a(?!S)', etc.
reg = re.compile(r'w ')
print(extract_all_after_pattern(search_after_rx, reg, text))
# => ['Newliner', 'Chatacter', 'in', '10000', 'the', 'Middle', 'of', 'the', 'sentence']
 

Посмотрите эту демонстрацию Python.

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

 import re

def extract_all_after_string(search_after, reg, text):
    start = text.find(search_after)
    if start >= 0:
        # print(f"Found at {start}, looking from {start len(search_after)}, i.e. in '{text[start len(search_after):]}'")
        # Found at 8, looking from 10, i.e. in 'Newliner Chatacter in 10000 the Middle of the sentence'
        return reg.findall(text, start len(search_after))
    return []
        
text = "we have a Newliner Chatacter in 10000 the Middle of the sentence"
search_after = "a "
reg = re.compile(r'w ')
print(extract_all_after_string(search_after, reg, text))
# => ['have', 'a', 'Newliner', 'Chatacter', 'in', '10000', 'the', 'Middle', 'of', 'the', 'sentence']
 

Посмотрите эту демонстрацию Python.

regex Способ пайпи

Чтобы извлечь совпадения после определенной строки с помощью одного регулярного выражения, вам необходимо установить модуль регулярных выражений PyPI (запустить pip install regex в вашем терминале), а затем использовать G регулярное выражение на основе (см. «Продолжение в конце предыдущего совпадения»).:

 import regex
text = "we have a Newliner Chatacter in 10000 the Middle of the sentence"
pattern = r'(?:G(?!^)|bab)W*(w )'
print(regex.findall(pattern, text))
# => ['Newliner', 'Chatacter', 'in', '10000', 'the', 'Middle', 'of', 'the', 'sentence']
 

Смотрите демонстрацию регулярных выражений и демонстрацию Python. Подробные сведения:

  • (?:G(?!^)|bab) — либо конец предыдущего матча, либо целое слово a
  • W* — ноль или более символов без слов (это необходимо использовать, чтобы перейти к следующему фрагменту символов слов)
  • (w ) — Группа 1 (значение, возвращаемое regex.findall ): один или несколько символов слов.

Комментарии:

1. Большое спасибо за подробные объяснения

2. @Ravi Этот ответ является общим, он очень поможет другим решить аналогичные проблемы. Подумайте о том, чтобы принять этот ответ.

Ответ №3:

Спросите себя, действительно ли вам нужны регулярные выражения? Может быть, функции генератора будет достаточно.

 def words_after_stop_word(sentence, stop_word=None):
    for w in sentence.split():
        if stop_word == None:
            yield w
        elif w == stop_word:
            stop_word = None

sentence = 'we have a Newliner Chatacter in 10000 the Middle of the sentence'
for w in words_after_stop_word(sentence, 'a'):
    print(w)
 

Демонстрация на Рекстестере.

Вы также можете найти начало стоп-слова и прервать предложение после него.

 def words_after_stop_word(sentence, stop_word=None):
    if stop_word == None:
        l = sentence.split()
    else:
        p = f' {sentence} '.find(f' {stop_word} ')
        l = [] if p == -1 else sentence[p   len(stop_word)   1:].split()
    return l

sentence = 'we have a Newliner Chatacter in 10000 the Middle of the sentence'
print(words_after_stop_word(sentence, 'a'))
 

Демонстрация на Рекстестере.