Совпадение простой строки с регулярным выражением не работает? - PullRequest
0 голосов
/ 31 декабря 2018

У меня большой txt-файл, и я хочу извлечь все строки с этими шаблонами:

/m/meet_the_crr
/m/commune
/m/hann_2

Вот что я попробовал:

import re

with open("testfile.txt", "r") as text_file:
    contents = text_file.read().replace("\n", "")

print(re.match(r'^\/m\/[a-zA-Z0-9_-]+$', contents))

В результате я получаюпросто "Нет".Что я тут не так делаю?

Ответы [ 3 ]

0 голосов
/ 31 декабря 2018

Вы читаете весь файл в переменную (в память), используя .read().replace("\n", "") вы перезапускаете все новые строки в строке.re.match(r'^\/m\/[a-zA-Z0-9_-]+$', contents) пытается сопоставить строку, которая полностью соответствует шаблону \/m\/[a-zA-Z0-9_-]+, и это невозможно после всех предыдущих манипуляций.

Есть как минимум два выхода.Либо удалите .replace("\n", "") (чтобы предотвратить удаление новой строки) и используйте re.findall(r'^/m/[\w-]+$', contents, re.M) (опция re.M включит сопоставление целых строк , а не всего текста), либо прочитайте файл построчно и используйте свой *Версия 1012 * для проверки каждой строки на совпадение и, если она совпадает, добавьте в окончательный список.

Пример:

import re
with open("testfile.txt", "r") as text_file:
    contents = text_file.read()
    print(re.findall(r'^/m/[\w-]+$', contents, re.M))

Или

import re
with open("testfile.txt", "r") as text_file:
    for line in text_file:
        if re.match(r'/m/[\w-]+\s*$', line):
            print(line.rstrip())

Примечание Iиспользовал \w, чтобы сделать шаблон несколько короче, но если вы работаете в Python 3 и хотите только сопоставлять буквы и цифры ASCII, используйте также параметр re.ASCII.

Кроме того, / не являетсяспециальный символ в шаблонах регулярных выражений Python, избавляться от него не нужно.

0 голосов
/ 31 декабря 2018

Вам нужно , а не удалить строки и использовать флаг re.MULTILINE, чтобы получить несколько результатов из большего текста:

# write a demo file
with open("t.txt","w") as f:
    f.write("""
/m/meet_the_crr\n
/m/commune\n
/m/hann_2\n\n
# your text looks like this after .read().replace(\"\\n\",\"\")\n
/m/meet_the_crr/m/commune/m/hann_2""")

Программа:

import re

regex = r"^\/m\/[a-zA-Z0-9_-]+$"

with open("t.txt","r") as f:
    contents = f.read()

found_all =  re.findall(regex,contents,re.M) 

print(found_all)
print("-")
print(open("t.txt").read())

Вывод:

['/m/meet_the_crr', '/m/commune', '/m/hann_2'] 

Содержание файла:

/m/meet_the_crr

/m/commune

/m/hann_2


# your text looks like this after .read().replace("\n","")

/m/meet_the_crr/m/commune/m/hann_2

Это то, что Wiktor Stribiżew действительно сказал вам в своем комментарии - хотя он предложил использоватьлучший образец: r'^/m/[\w-]+$'

0 голосов
/ 31 декабря 2018

В вашем коде нет ничего логически неправильного, и фактически ваш шаблон будет соответствовать вводимым вами данным:

result = re.match(r'^\/m\/[a-zA-Z0-9_-]+$', '/m/meet_the_crr')
if result:
    print(result.groups())    # this line is reached, as there is a match

Поскольку вы не указали никаких групп захвата, вы увидите, как печатается ()на консоль.Вы можете захватить весь ввод, и тогда он будет доступен, например,

result = re.match(r'(^\/m\/[a-zA-Z0-9_-]+$)', '/m/meet_the_crr')
if result:
    print(result.groups(1)[0])

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