python反向引用正则表达式

时间:2015-07-13 14:00:22

标签: python regex

我需要搜索这样的内容:

lines = """package p_dio_bfm is
   procedure setBFMCmd (  
      variable  pin : in tBFMCmd
      );
end p_dio_bfm; -- end package;

package body p_dio_bfm is
   procedure setBFMCmd (  
      variable  pin : in tBFMCmd
      ) is
   begin
      bfm_cmd := pin;
   end setBFMCmd;
end p_dio_bfm;"""

我需要提取包名,即p_dio_bfm和包声明,即"包p_dio_bfm之间的部分是"和FIRST"结束p_dio_bfm;"

问题是包声明可能以" end p_dio_bfm;"结束。或者"结束包裹;"所以我尝试了以下" OR"正则表达式: - 适用于以" end package"结尾的包裹。 - 对于以" end pck_name;"

结尾的包不起作用
pattern = re.compile("package\s+(\w+)\s+is(.*)end\s+(package|\1)\s*;")
match = pattern.search(lines)

问题是正则表达式的(package | \ 1)部分,在那里我要抓住单词" package"或匹配的包名。

更新:我提供了一个完整的代码,希望能澄清它:

import re
lines1 = """package p_dio_bfm is
   procedure setBFMCmd (
      variable  pin : in tBFMCmd
      );
end p_dio_bfm;

package body p_dio_bfm is
   procedure setBFMCmd (
      variable  pin : in tBFMCmd
      ) is
   begin
      bfm_cmd := pin;
   end setBFMCmd;
end p_dio_bfm;"""

lines2 = """package p_dio_bfm is
   procedure setBFMCmd (
      variable  pin : in tBFMCmd
      );
end package;

package body p_dio_bfm is
   procedure setBFMCmd (
      variable  pin : in tBFMCmd
      ) is
   begin
      bfm_cmd := pin;
   end setBFMCmd;
end package;"""

lines1 = lines1.replace('\n', ' ')
print lines1

pattern = re.compile("package\s+(\w+)\s+is(.*)end\s+(package|\1)\s*;")
match = pattern.search(lines1)

print match

lines2 = lines2.replace('\n', ' ')
print lines2

match = pattern.search(lines2)

print match

我希望在这两种情况下,使用独特的正则表达式来取回这部分:

"""procedure setBFMCmd (
          variable  pin : in tBFMCmd
          );"""  

没有我删除的\ n字符。

2 个答案:

答案 0 :(得分:3)

你的正则表达式不匹配任何东西,因为它不正确。没有使用多行标记.*不匹配新行字符,所以你可以使用{{1} }:

[\s\S]*

请参阅演示https://regex101.com/r/tZ3uH0/1

但是在这里还有一些问题,你的字符串包含2个包块,而且这一点,作为一种更优雅和有效的方式,你可以起诉r'package ([^\s]+)\s+is([\s\S]*)end\s+(package|\1)\s*;' 标志来制作'。&#39 ;特殊字符匹配任何字符,包括换行符。所以你可以编写你的正则表达式如下:

re.DOTALL

但这仍然会与第一个街区匹配:

pattern = re.compile("package\s+(\w+)\s+is(.*)end\s+(package|\1)\s*;",re.DOTALL)

为了匹配所有块,您需要澄清第二组中的>>> match = pattern.search(lines) >>> print match.group(0) package p_dio_bfm is procedure setBFMCmd ( variable pin : in tBFMCmd ); end p_dio_bfm; -- end package; >>> print match.group(1) p_dio_bfm >>> print match.group(2) procedure setBFMCmd ( variable pin : in tBFMCmd ); end p_dio_bfm; -- >>> print match.group(3) package 这样的词:

body

请参阅演示https://regex101.com/r/tZ3uH0/3

答案 1 :(得分:2)

怎么样:

>>> for row in re.findall(
...   r'package(?:\s.*?)(?P<needle>[^\s]+)\s+is\s+(.*?)end\s+(?:package|(?P=needle));',
...   lines,
...   re.S
... ):
...   print '{{{', row[1], '}}}'
...
{{{ procedure setBFMCmd (
      variable  pin : in tBFMCmd
      );
}}}
{{{ procedure setBFMCmd (
      variable  pin : in tBFMCmd
      ) is
   begin
      bfm_cmd := pin;
   end setBFMCmd;
}}}

我冒昧地不过滤掉@ mihai-hangiu如何通过包括第二个区块来解释。