首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python regex:跨多行搜索

Python regex:跨多行搜索
EN

Stack Overflow用户
提问于 2015-07-20 21:51:27
回答 3查看 989关注 0票数 2

我正在编写一个python脚本来解析包含以下数据的文件:

代码语言:javascript
复制
// some more entries with different structures.
leaf a include-1 {
 type 1;
 description "test1";
}
leaf b include-2 {
 type string;
 description "test2";
}
// some other entries

我想获得我所有的叶子名称和它的描述,例如:

代码语言:javascript
复制
a test1
b test2

我尝试了以下操作:

代码语言:javascript
复制
 regExStr = '^leaf.*{.*include-.*}$'
 compiled =  re.compile(regExStr, re.DOTALL | re.MULTILINE)
 matched = compiled.search(line)

换句话说,我想从leaf开始搜索,然后是任意数字字符,然后是{,然后是include-,最后是}

因为我已经使用了re.DOTALL | re.MULTILINE,所以我的.也包含了新的一行。

但是我不能得到想要的结果。这里我漏掉了什么?

EN

回答 3

Stack Overflow用户

发布于 2015-07-20 22:01:37

可以使用re.S (=re.DOTALL)修饰符使用正则表达式跨多行进行搜索。为了能够匹配行首,应该使用re.M (多行模式)。这些名称有点棘手,但它们可以组合在一起。

您可以使用更新的正则表达式获取结果:

代码语言:javascript
复制
p = re.compile(r'^leaf\s+(\S+)[^{]*\{[^}]*\bdescription\s+"([^"]+)"[^}]*}', re.S|re.M)
test_str = "leaf a include-1 {\n type 1;\n description \"test1\";\n}\nleaf b include-2 {\n type string;\n description \"test2\";\n}"
print ["%s %s"%(x.group(1), x.group(2)) for x in re.finditer(p, test_str)]

请参阅IDEONE demo

输出:

代码语言:javascript
复制
['a test1', 'b test2']

正则表达式匹配:

  • ^ - line
  • leaf的开始-全词literally
  • \s+(\S+) -1或更多空格,然后捕获一个或更多非空格characters
  • [^{]* -0或更多除{
  • \{之外的字符的序列-文字{
  • [^}]* -0或更多不同于}
  • \bdescription的字符-全词description
  • \s+"([^"]+)" -1或更多空格符号,然后是",然后捕获除双引号以外的1个或多个字符,然后匹配除quote
  • [^}]*
  • }以外的另一个双}.

-0或多个字符-文字}.

票数 1
EN

Stack Overflow用户

发布于 2015-07-20 21:56:25

如果格式始终相同,则可以使用dict和str.split:

代码语言:javascript
复制
d = {}
with open("in.txt") as f:
    for line in f:
        if line.startswith("leaf"):
            key = line.split(None,2)[1]
            next(f)
            val = next(f).split()[-1].strip(";\n")
            d[key]=val

for k,v in d.items():
    print(k,v)

输出:

代码语言:javascript
复制
('a', '"test1"')
('b', '"test2"')
票数 0
EN

Stack Overflow用户

发布于 2015-07-20 22:13:41

我使用了finditer,这样你就可以遍历多个匹配:

代码语言:javascript
复制
import re

line = """leaf a include-1 {
 type 1;
 description "test1";
}
leaf b include-2 {
 type string;
 description "test2";
}"""

regExStr = '^leaf (\w) include-.*?description \"(.*?)\";.*?}'
compiled =  re.compile(regExStr, re.DOTALL | re.MULTILINE)
matched = compiled.finditer(line)
for m in matched:
    print m.groups()

打印:

代码语言:javascript
复制
('a', 'test1')
('b', 'test2')

您可以看到,每个结果都是一个元组,其中第一个元素(m.group(1))是您的叶子名称,第二个元素(m.group(2))是描述。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31518294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档