从字符串中提取指定正则表达式匹配的文本

如果想解析由编译器/链接器生成的映射文件,则需要编写一个脚本。映射文件通常如下所示:

%SEGMENT_SECTION
                                                      Start Address  End Address
--------------------------------------------------------------------------------
Segment Name: S1_1, Segment Type: .bss                0A000000       0A050F23
--------------------------------------------------------------------------------
area1_start.o (.bss)                                  0A000000       0A000003
...

                                                      Start Address  End Address
--------------------------------------------------------------------------------
Segment Name: S2_1, Segment Type: .bss                0A050F24       0A060000
--------------------------------------------------------------------------------
area2_start.o (.bss)                                  0A000000       0A000003

...

%NEXT_SECTION

可以使用 Python 的 re 模块来解析此类文件,但想以一种非常简单的方式来编写正则表达式,以便于解析。基本步骤如下:

with open('blah.map') as f:
    text = f.read()

# ... 解析文件以将文本更新为 "%SEGMENT_SECTION" 之后的文本

match = segment_header_re.match(text)
seg_name, seg_type, start_addr, end_addr = match.groups()
# ... (利用匹配的值)

text = text[len(match.matched_str):]

# 解析其余的文本

但是,不知道如何获取匹配字符串的长度,即伪代码中的 match.matched_str。在 Python 的 re 文档中也没有找到相关信息。有没有更好的方法来进行这种解析?

2、解决方案

方法一:使用 match.span 方法

可以使用 match.span 方法来实现。match.span() 方法返回一个元组,其中包含匹配字符串的起始索引和结束索引。例如:

>>> s = 'The quick brown fox jumps over the lazy dog'
>>> m = re.search('brown', s)
>>> m.span()
(10, 15)

然后,可以使用 match.span() 方法来获取匹配字符串的长度:

>>> start, end = m.span()
>>> s[end:]
' fox jumps over the lazy dog'

方法二:使用 match.end 方法

也可以使用 match.end 方法来获取匹配字符串的长度:

>>> s[m.end():]
' fox jumps over the lazy dog'

方法三:使用正则表达式对象

另一个选择是使用正则表达式对象,该对象可以采用 posendpos 参数来将搜索范围限制在字符串的一部分。例如:

>>> s = 'The quick brown fox jumps over the lazy dog'
>>> over = re.compile('over')
>>> brown = re.compile('brown')
>>> m_brown = brown.search(s)
>>> m_brown.span()
(10, 15)
>>> m_over = over.search(s)
>>> m_over.span()
(26, 30)

brown 匹配的末尾开始搜索 over

>>> match = over.search(s, pos = m_brown.end())
>>> match.group()
'over'
>>> match.span
(26, 30)

over 匹配的末尾开始搜索 brown,不会产生匹配结果。

>>> match = brown.search(s, m_over.end())
>>> match.group()

Traceback (most recent call last):
  File "<pyshell#71>", line 1, in <module>
    match.group()
AttributeError: 'NoneType' object has no attribute 'group'
>>> print(match)
None

对于较长的字符串和多次搜索,使用带起始位置参数的正则表达式对象肯定会加快速度。

方法四:使用 match.group 方法

还可以使用 .group() 方法。整个匹配的字符串可以通过 match.group(0) 检索:

text = text[len(match.group(0)):]

但是,请注意,如果未匹配,这会引发 AttributeError

>>> re.match('xyz', 'abcde').group(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

因此,在调用匹配对象的方法之前,可能需要实现一个检查来确保匹配成功。

猜你喜欢

转载自blog.csdn.net/D0126_/article/details/143573841