如何使用正则表达式进行标记化,使"其他所有内容的正则表达式与"特殊令牌的正则表达式不匹配?

How to tokenize using regular expression such that regex for quot;everything elsequot; does not match regex for quot;special tokensquot;?(如何使用正则表达式进行标记化,使quot;其他所有内容的正则表达式与quot;特殊令牌的正则表达式不匹配?) - IT屋-程序员软件开发技术分享
本文介绍了如何使用正则表达式进行标记化,使"其他所有内容的正则表达式与"特殊令牌的正则表达式不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下类型的文本要标记。

文本:

<!-- foo-bar --> Text1 <!-!> <!-- bar-baz --> Text2

我想将其标记为三种标记:COMMENT_STARTCOMMENT_ENDOTHER

例如,对于上面的文本,我需要以下输出。

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_STARTCOMMENT_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这样的解析库,它们比普通的正则表达式更适合进行这种解析。

这篇关于如何使用正则表达式进行标记化,使&quot;其他所有内容的正则表达式与&quot;特殊令牌的正则表达式不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Leetcode 234: Palindrome LinkedList(Leetcode 234:回文链接列表)
How do I read an Excel file directly from Dropbox#39;s API using pandas.read_excel()?(如何使用PANDAS.READ_EXCEL()直接从Dropbox的API读取Excel文件?)
subprocess.Popen tries to write to nonexistent pipe(子进程。打开尝试写入不存在的管道)
I want to realize Popen-code from Windows to Linux:(我想实现从Windows到Linux的POpen-code:)
Reading stdout from a subprocess in real time(实时读取子进程中的标准输出)
How to call type safely on a random file in Python?(如何在Python中安全地调用随机文件上的类型?)