本文介绍了如何使用正则表达式进行标记化,使";其他所有内容的正则表达式与";特殊令牌的正则表达式不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有以下类型的文本要标记。
文本:
<!-- foo-bar --> Text1 <!-!> <!-- bar-baz --> Text2
我想将其标记为三种标记:COMMENT_START
、COMMENT_END
和OTHER
。
例如,对于上面的文本,我需要以下输出。
COMMENT_START <!--
OTHER foo-bar
COMMENT_END -->
OTHER Text1 <!-!>
COMMENT_START <!--
OTHER bar-baz
COMMENT_END -->
OTHER Text2
受https://docs.python.org/3.4/library/re.html#writing-a-tokenizer启发,我编写了此程序。
import re
def tokenize(code):
token_specification = [
('COMMENT_START', '<!--'),
('COMMENT_END', '-->'),
('OTHER', '.*')
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group(kind)
print(kind, value)
test_string = '<!-- foo-bar --> Text1 <!-!> <!-- bar-baz --> Text2'
tokenize(test_string)
但它没有提供所需的输出。这是我得到的输出。
COMMENT_START <!--
OTHER foo-bar --> Text1 <!-!> <!-- bar-baz --> Text2
OTHER
问题是OTHER
的正则表达式正在消耗整个字符串。
OTHER
的正则表达式用于匹配除<!--
和-->
等特殊标记之外的所有其他标记。
我如何才能正确地编写此程序,使OTHER
的正则表达式不使用<!--
或-->
,而不使用它,以便以后它们可以由COMMENT_START
和COMMENT_END
的正则表达式匹配?
更广泛地说,如何编写一个令牌化器来生成我们感兴趣的特殊令牌以及其他所有令牌?
推荐答案
问题是other
表达式将匹配任何内容,甚至是注释。要解决此问题,您有两个选择。一种方法是使other
只匹配一个字符,然后将"Other"字符串折叠为单个"Other"。如下所示:
token_specification = [
('COMMENT_START', '<!--'),
('COMMENT_END', '-->'),
('OTHER', '.')
]
然后输出为:
COMMENT_START <!--
OTHER
OTHER f
OTHER o
OTHER o
OTHER
COMMENT_END -->
OTHER
OTHER T
OTHER e
OTHER x
OTHER t
OTHER 1
(etc. . . .)
通过只匹配"Other"中的一个字符,您就给了它在每个位置查找注释的机会。然后,您必须迭代令牌列表并组合连续的"其他"令牌。
另一种方法是使other
不贪婪,并包括其他令牌类型的先行检查:
token_specification = [
('COMMENT_START', '<!--'),
('COMMENT_END', '-->'),
('OTHER', r'.*?(?=-->|<!--)')
]
这将提供您所需的输出:
COMMENT_START <!--
OTHER foo
COMMENT_END -->
OTHER Text1
COMMENT_START <!--
OTHER bar
COMMENT_END -->
但是,此解决方案的可扩展性较差,因为您必须重复other
中的其他令牌。如果您有更多类型的令牌,这将变得不方便。
我建议您研究一下像parcon或pyparsing这样的解析库,它们比普通的正则表达式更适合进行这种解析。
这篇关于如何使用正则表达式进行标记化,使";其他所有内容的正则表达式与";特殊令牌的正则表达式不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!