2

我有一个格式为

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

4

3 回答 3

2

如果我正确理解了要求:

a1=re.search(r'_abc(.*)xyz',line,re.DOTALL)
print a1.group(1)

使用 re.DOTALL 将启用 . 也匹配换行符。

于 2013-07-29T02:05:00.887 回答
0

听起来您对*正则表达式中符号的含义有误解。这并不意味着“匹配任何东西”,而是“重复前面的事情零次或多次”。

要匹配任何字符串,您需要结合*with .,它匹配任何单个字符(几乎,稍后会详细介绍)。该模式.*匹配任何零个或多个字符的字符串。

所以,你可以改变你的模式.*abc(.*)xyz,你会在那里。.*但是,如果前缀和后缀在文本中只存在一次,则不需要前导。您可以省略它,让正则表达式引擎处理跳过abc前缀之前的任何不匹配字符。

剩下的一个问题是源文本中有多行文本。我在上面提到了.模式匹配字符,但这并不完全正确。默认情况下,它不会匹配换行符。对于单行文本没关系,但它会在这里给你带来问题。要更改该行为,您可以将标志re.DOTALL(或其较短的拼写,re.S)作为第三个参数传递给re.findallor 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

我已经稍微简化了模式,因为您的评论建议您要获取整个匹配的文本,而不仅仅是前缀和后缀之间的部分。

于 2013-07-29T02:48:46.107 回答
0

当它包含特殊字符时,您re.escape在模式上使用它,因此它无法正常工作。

>>>>re.escape("*_abc:")
'\\*_abc\\:'

这将匹配实际的短语*_abc:,但这不是你想要的。

只需发出 re.escape 调用,它应该或多或少地正常工作。

于 2013-07-29T02:06:30.000 回答