【问题标题】:Regex passes in Rubular but not in Python正则表达式在 Rubular 中通过,但在 Python 中不通过
【发布时间】:2012-07-11 23:24:28
【问题描述】:
import re
import urllib.request
file_txt = urllib.request.urlopen("ftp://ftp.sec.gov/edgar/data/1408597/0000930413-12-003922.txt")
pattern_item4= re.compile("(Item\\n*\s*4.*)Item\\n*\s*5")
print(re.search(pattern_item4,bytes.decode(f)))
#Returns None

这个正则表达式以 rubular 形式返回我想要的,但显然它没有达到 Python 的预期效果。有人能帮我解决这个问题吗? 正则表达式的目的基本上是提取 item4 和 item5 之间的内容。

谢谢

【问题讨论】:

  • \\n* 没有效果。它必须是:[\n]*(或 [\\n]*,取决于您传递此字符串)。
  • 谢谢,杰克。这个技巧也不管用。我尝试了你的建议,但没有运气..
  • 您检查过我的回答并检查过file_txt 中确实有数据吗?还有f 是从哪里来的bytes.decode(f)
  • @zsljulius:如果您发布您想要提取的确切部分,也许我们可以详细说明一个正则表达式。
  • 嘿乔恩,所以文件是从 sec 的 ftp 服务器传输的。它是txt格式的。但是,该文件更像是一个 xml 文件。 urllib.request.urlopen 给了我一个类似对象的文件,如果我只做 file_txt.read(),我不能直接应用 re.search。这就是为什么我使用 bytes.decode(f) 将其变成类似对象的字符串的原因。我也尝试过 str(f),但是 str(f) 会以某种方式截断我需要的任何内容。所以我最后求助于 bytes.decode(f) 来获取原始字符串

标签: python regex python-3.x


【解决方案1】:

你需要 re.DOTALL 标志否则. 不匹配换行符。要在 EOL 匹配 Item,您可以使用带有 re.MULTILINE 标志的 $

pattern = re.compile(r"(Item$\s*4.*)Item$\s*5", re.S | re.M)

【讨论】:

  • 你不需要那个$。它所做的只是强制\s* 匹配换行符,因此您可以将其写为\n\s*。但我很确定任何空白字符都可以,这就是我在回答中使用\s+ 的原因。
  • 太棒了!有用!我什至不知道点默认不匹配换行符!你拯救了我的一天!
  • 如果您假设所有所需的匹配项都将在Item 之后立即包含换行符,但这对我来说似乎是格式化的意外。数字后面的. 似乎是一个更可靠的指标。
【解决方案2】:

尝试使用原始字符串

re.compile (r"(Item\\n*\s*4.*)Item\\n*\s*5")

我猜这与您转义 \n 有关。但是,如果不确切知道您期望匹配的是什么,就不可能说出来。

【讨论】:

  • 我同意这是 \n 转义...但无法确定
  • 感谢您的回复。不幸的是,原始字符串技巧不起作用。我猜 \\n 是正确理解 '\n' 的正确方法?
【解决方案3】:

知道换行符的位置并不能帮助您找到匹配项,因此无需专门匹配\n;它只是另一个空白字符。试试这个:

r"(?s)Item\s+4\..*?(?=Item\s+5\.)"

(?s) 使 . 能够匹配换行符,因此 .*? 会消耗所有内容,直到前瞻 - (?=Item\s*\d+\.) - 发现下一个“项目”条目的开头。如果您想遍历所有项目,可以将45 替换为\d+

【讨论】:

    猜你喜欢
    • 2014-03-12
    • 1970-01-01
    • 2018-03-09
    • 2011-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    相关资源
    最近更新 更多