如何允许正则表达式返回空字符串

时间:2016-11-08 19:52:18

标签: python regex

我有一系列要解析的文本文件,这些文件可能包含也可能不包含任何一个标题集,然后是该标题下面的数据行或注释。所有标题组前面都有一个双重换行符。

我正在寻找一个正则表达式,如果它看到一个标题后面紧跟一个双重换行符将返回一个空字符串。我需要区分文档是否具有没有内容的标题,或者根本没有该标题。

例如,以下是两份文件的部分内容:

Dogs
Spaniel
Beagle

Birds
Parrot

Dogs

Amphibians
Frogs
Salamanders

我想要一个在第一个文档中返回Spaniel\nBeagle的正则表达式,并在第二个文档中返回一个空字符串。

我能找到的最接近的是(在Python语法中)expr = re.compile("Dogs(.+?|)?\n\n, re.DOTALL)。这将返回第一个的正确值,但在第二种情况下,它返回\n\nAmphibians\nFrogs\nSalamanders。第二个问号和管道不能达到我的期望。

我现在正在通过程序逻辑处理这个问题,搜索Dogs\n\n并且只返回内容,如果找不到正则表达式,但是它不令人满意,因为没有什么能胜过单个正则表达式做这项工作的感觉。 / p>

那么:是否有与第二个文档匹配的正则表达式,并返回""

1 个答案:

答案 0 :(得分:0)

<强>问题

您的Dogs(.+?|)?\n\n模式与文档中任意位置的Dogs匹配,然后尝试可选(因为有一个空的替代|))匹配任何< em> 1或更多(由于+?量词)字符,但尽可能少(因为+? lazy 量词),直到第一个2个换行符。

这意味着,只有当文本中某处没有双重换行符号时,正则表达式才匹配Dogs,或者它将抓取任何文本,直到第一个双换行符号为止,因为{{1消耗1个换行符,.+?模式部分将无法在\n\n之后找到2个换行符。

<强>解决方案

您可以使用Dogs量词而不是*?来量词来匹配零个或多个个字符。 Dogs(.*?)\n\n会发现+?,任意0个字符尽可能少,直到第一个Dogs,甚至是\n\n之后出现的字符。

<强>优化

如果处理非常长的字符串,并且Dogs出现在行的开头,则可以使用展开的正则表达式,因为已知Dogs可以减慢使用更长输入的正则表达式执行。

使用

.*?

请参阅regex demo

基本上,它会匹配

  • expr = re.compile(r"^Dogs(.*(?:\n(?!\n).*)*)", re.MULTILINE) - 开始行
  • ^ - Dogs substring
  • Dogs - 第1组捕获:
    • (.*(?:\n(?!\n).*)*) - 除了换行符之外的零个或多个字符(因为未使用.*修饰符)
    • re.DOTALL - 零个或多个序列:
      • (?:\n(?!\n).*)* - 换行符后面没有其他换行符
      • \n(?!\n) - 除了换行符之外的零个或多个字符