【问题标题】:Matching a simple string with regex not working?用正则表达式匹配一个简单的字符串不起作用?
【发布时间】:2019-05-28 00:45:15
【问题描述】:

我有一个大的 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))

我得到的结果是一个简单的“无”。我在这里做错了什么?

【问题讨论】:

  • 删除.replace("\n", "")并使用re.findall(r'^/m/[\w-]+$', contents, re.M)
  • 尝试将 print 语句放在 with 语句块中。
  • @PatrickArtner 我匹配所有 3 个。所以它似乎不是正则表达式。
  • @TAN-CF-OK .. 现在使用 real 文本,你正在给正则表达式工作..删除 @987654328 @ .. 你的文字是 /m/meet_the_crr/m/commune/m/hann_2 - 里面没有换行符 .. 仍然匹配所有内容?
  • 对 url 事故感到抱歉:它是 regex101.com -您的特殊情况在这里:regex101.com/r/PyNjiE/1 .. 它使用多行标志

标签: python regex match


【解决方案1】:

您需要删除线端并使用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-]+$'

【讨论】:

    【解决方案2】:

    您正在使用.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 选项将启用匹配整个而不是整个文本),或者逐行读取文件并使用您的re.match 版本检查每一行是否匹配,如果匹配则添加到最终列表中。

    例子:

    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())
    

    请注意,我使用\w 使模式更短一些,但如果您使用 Python 3 并且只想匹配 ASCII 字母和数字,也请使用re.ASCII 选项。

    另外,/ 不是 Python 正则表达式模式中的特殊字符,无需转义。

    【讨论】:

    • 我不敢相信您实际上给出的答案涉及正则表达式以外的内容。新年决心?
    • @TimBiegeleisen Python 已经成为我的主要编程语言将近一年了。
    【解决方案3】:

    您的代码在逻辑上没有任何问题,实际上您的模式将匹配您描述的输入:

    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
    

    【讨论】:

    • txt 文件有问题吗?我现在只得到“[]”。
    • 只要我不把文本文件放在那里,它就可以工作。
    猜你喜欢
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-30
    相关资源
    最近更新 更多