我有一个格式为
的文件sjaskdjajldlj_abc:
cdf_asjdl_dlsf1:
dfsflks %jdkeajd
sdjfls:
adkfld %dk_.(%sfj)sdaj, %kjdflajfs
afjdfj _ajhfkdjf
zjddjh -15afjkkd
xyz
我希望在第一行的字符串_abc:
和最后一行的xyz
之间找到文本。
我已经尝试过打印
re.findall(re.escape("*_abc:")+"(*)"+re.escape("xyz"),line)
但我得到null
。
答案 0 :(得分:2)
如果我理解正确的要求:
a1=re.search(r'_abc(.*)xyz',line,re.DOTALL)
print a1.group(1)
使用将启用的re.DOTALL。也匹配换行符。
答案 1 :(得分:0)
当您的模式包含特殊字符时,您使用了re.escape
,因此无法使用它。
>>>>re.escape("*_abc:")
'\\*_abc\\:'
这将匹配实际的短语*_abc:
,但这不是您想要的。
只需调用re.escape,它就可以正常工作。
答案 2 :(得分:0)
听起来你对*
符号在正则表达式中的含义有误解。它并不意味着“匹配任何东西”,而是“重复之前的事情零次或多次”。
要匹配任何字符串,您需要将*
与.
结合使用,该.*
匹配任何单个字符(稍后会更多)。模式.*abc(.*)xyz
匹配任何零个或多个字符的字符串。
因此,您可以将模式更改为.*
,并且您将大部分时间都在那里。但是,如果前缀和后缀仅在文本中存在一次,则前导abc
是不必要的。您可以省略它,只需让正则表达式引擎处理.
前缀之前跳过任何不匹配的字符。
剩下的一个问题是源文本中有多行文本。我在上面提到re.DOTALL
模式符合字符,但这并不完全正确。默认情况下,它与新行不匹配。对于无关紧要的单行文本,但这会给你带来麻烦。要更改此行为,您可以将标记re.S
(或其较短的拼写re.findall
)作为第三个参数传递给re.search
或.
。该标志告诉正则表达式系统允许import re
def find_between(prefix, suffix, text):
pattern = r"{}.*{}".format(re.escape(prefix), re.escape(suffix))
result = re.search(pattern, text, re.DOTALL)
if result:
return result.group()
else:
return None # or perhaps raise an exception instead
模式匹配任何字符,包括换行符。
所以,以下是将当前代码转换为工作系统的方法:
{{1}}
我简化了模式,因为你的评论建议你想得到整个匹配的文本,而不仅仅是前缀和后缀之间的部分。