正则表达式的负面展望?只能匹配片段的第一个尖括号

时间:2019-04-03 15:42:34

标签: python regex

我正在尝试修改我工作的正则表达式(使用Python 3.6)以处理测试数据。您可以看到

str =“ < @@@@@ 2018年7月2日工业界。Lorem Ipsum自1500年代以来一直是行业的标准伪文本,当时一台未知的打印机采用了一个厨房类型并将其打乱到制作了一个标本册,它不仅生存了五个世纪,而且跳入了电子版印刷的历程,但基本上保持不变,在1960年代随着包含莱勒姆·伊普森(Lerem Ipsum)段落的Letraset床单的发行而得到普及。 ,以及最近使用的Aldus PageMaker等桌面发布软件,包括Lorem Ipsum的版本> << em> @@@@@ August 1st 2019 ustry。Lorem Ipsum自1500年代以来一直是业界的标准伪文本。一位不知名的打印机拿了一个样板间,然后加印成一本样本,它不仅生存了五个世纪,而且还飞跃到电子排版上,>基本上保持不变。它在1960年代随着Letraset的发行而流行$$$$$$$ ets个包含Lorem Ipsum段落和m只能使用Aldus PageMaker之类的桌面发布软件(包括Lorem Ipsum << em> 2019年8月2日)来收集矿石,而Aldus PageMaker等之类的桌面发布软件则包括Lorem Ipsum> << em> @ @@@ 2019年8月1日。自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿来一个厨房,并争先恐后地将它编成样本书。它不仅生存了五个世纪,而且在电子排版方面也获得了飞跃,>基本上保持不变。它在1960年代得到了普及,发布了包含Lorem Ipsum段落的Letraset图纸,最近还发布了Aldus PageMaker等桌面出版软件,其中包括Lorem Ipsum>“

您会看到有一堆由尖括号分隔的片段,在此情况下,我感兴趣的每个片段都以一个易于识别的字符串开头(在这种情况下@@@一些日期,而片段以尖括号结束,所以就像<@ @@@某些日期可能包含尖括号的文本>

< @@@@@ 2018年7月2日。自1500年代以来,Lorem Ipsum一直是行业的标准伪文本,当时一位不知名的打印机拿起一个厨房,将其打乱成一本样本书。它不仅生存了五个世纪,而且在电子排版方面也获得了飞跃,>基本上保持不变。它在1960年代开始流行,发布了包含Lorem Ipsum段落的Letraset工作表,最近又发布了Aldus PageMaker等桌面发布软件,其中包括Lorem Ipsum>

问题在于,日期之后的文本有时包含一个尖括号,并且由于正则表达式的渴望仅会部分匹配。有办法防止这种情况吗?我无法成功使用负面的展望。

我已经尝试了以下方法:

r"<[(?!<@date) >| (?!<@date) < | ^>]+>

换句话说,如果出现在文本中,则匹配后跟<@日期的所有内容(包括尖括号<或>),也应匹配任何其他字符。

 pattern = re.compile(r"<[^>]+>")
 return pattern.findall(str)

实际结果是它仅部分匹配,因为正则表达式只渴望与文本中的第一个>或<匹配,而我想获得包括>之后的部分以及直到实际闭合尖括号的整个片段和下一个片段的开头(除非是最后一个片段,否则后面可能没有任何内容)。

1 个答案:

答案 0 :(得分:1)

您可以将左括号与@相乘1次,然后使用非贪心匹配.*?,直到遇到下一个<@或字符串末尾为止:

<\s*@+.*?(?=<@|$)

Regex demo | Python demo

您的代码可能如下:

pattern = re.compile(r"<\s*@+.*?(?=<@|$)", re.MULTILINE)
return pattern.findall(str)

我认为您要表达的另一种方式是使用tempered greedy token

<\s*@+(?:(?!<@+).)*>

Regex demo | Python demo