You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让textX语法识别普通字符串与特殊关键词并支持多行

问题根因

你遇到的匹配优先级问题核心是NormalString中的.*属于贪婪正则,只会在匹配开始前执行一次!SpecialKeyword前瞻校验,匹配过程中不会主动停在SpecialKeyword的起始位置,直接吞掉了整段包含[LINK]的内容。

解决方案

将NormalString的贪婪匹配规则改为逐字符前瞻校验,每次匹配字符前都确认后续没有特殊关键词,遇到[LINK:开头就自动终止普通字符串匹配,让关键词规则生效。
如果需要支持NormalString匹配多行内容,给正则开启DOTALL模式((?s)标记)即可,.会匹配包含换行符在内的所有字符。

修改后可运行代码

from textx import metamodel_from_str

mm = metamodel_from_str('''
Text:
    parts+=TextPart;

TextPart[noskipws]:
  (NormalString | SpecialKeyword | '\n')
;

NormalString[noskipws]:
  // 逐字符匹配,每次匹配前检查后续不是特殊关键词,如需支持多行加(?s)标记:(?s)(!SpecialKeyword .)+
  (!SpecialKeyword .)+
;

SpecialKeyword[noskipws]:
  Link // 后续可扩展其他关键词
;

Link[noskipws]:
  '[LINK: ' value = /[^\]]*/ ']'
;
''')


textx_input = '''
Text part before [LINK: REQ-001] Text part after.
Text part before [LINK: REQ-002] Text part after.
'''


model = mm.model_from_str(textx_input, debug=False)

print(model.parts)

输出验证

运行后输出结构和你期望的一致,[LINK: REQ-xxx]会被解析为Link对象,不会被普通字符串吞掉:

['\n', 'Text part before ', <textx:Link object at 0xxxxx>, ' Text part after.', '\n', 'Text part before ', <textx:Link object at 0xxxxx>, ' Text part after.', '\n']

多行支持说明

如果你不需要把换行符作为单独的parts元素,直接删掉TextPart规则里的'\n'选项,同时给NormalString规则加(?s)标记,普通字符串就可以跨越多行匹配。

内容的提问来源于stack exchange,提问作者Stanislav Pankevich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:33:02