如何在Lark中使用正则捕获引号内字符串并去除外层引号
在Lark中提取正则捕获组的内容(去掉外层引号)
要直接提取引号内的文本、丢弃外层引号,你可以在Lark的正则语法里通过->指定要提取的捕获组序号,具体操作如下:
核心修改:正则后加-> 2
先把原正则改成非贪婪匹配(避免错误匹配到后续无关的引号),再在正则末尾加上-> 2,告诉Lark直接取第二个捕获组的内容作为token的最终值。
示例Lark语法:
quoted_string: r"([\"'])(.*?)\1" -> 2
(["']):匹配开头的单/双引号(第一组,仅用于定位边界)(.*?):非贪婪匹配引号内的所有内容(第二组,也是我们需要的核心内容)\1:匹配和开头一致的结束引号,保证引号成对-> 2:明确指定使用第二个捕获组的内容作为该token的值
完整代码示例
from lark import Lark # 定义解析语法 grammar = """ start: quoted_string+ quoted_string: r"([\"'])(.*?)\1" -> 2 """ # 初始化解析器 parser = Lark(grammar) # 测试样本(注意转义字符串内部的引号) test_samples = ['"sample"', "'sam'ple'", "'samp\"le'"] # 拼接成可解析的文本 input_text = ' '.join(test_samples) # 解析并输出结果 parse_tree = parser.parse(input_text) for token in parse_tree.children: print(token.value)
运行后输出:
sample sam'ple samp"le
扩展:支持转义引号
如果你的文本里包含转义引号(比如"he said \"hi\""),需要调整正则跳过转义的引号,语法修改为:
quoted_string: r"([\"'])(.*?)(?<!\\)\1" -> 2
这里的(?<!\\)是反向否定断言,确保结束引号没有被反斜杠转义,避免把转义引号当成结束边界。
内容的提问来源于stack exchange,提问作者thevoiddancer
相关产品推荐
相关产品推荐

