如何从一行文本中解析关键字和字符串



有一个文件关键字.tx

Commands:
keywords = 'this' & 'way'
;
StartWords:
keywords = 'bag'
;

然后是一个文件 mygram.tx 与

import keywords
MyModel:
keyword*=StartWords[' ']
name+=Word[' ']
;
Word:
text=STRING
;

'''

我的数据文件有一行"这样包你好苏打水"。 希望看到结果具有关键字='袋子'名称='你好苏打水'和命令='这种方式'的属性。

不知道如何处理语法:关键字单词关键字确保单词中不包含第二个关键字。 另一种表达方式是开始词单词命令

如果我理解你的目标,你可以做这样的事情:

from textx import metamodel_from_str
mm = metamodel_from_str('''
File:
lines+=Line;
Line:
start=StartWord
words+=Word
command=Command;
StartWord:
'bag' | 'something';
Command:
'this way' | 'that way';
Word:
!Command ID;
''')
input = '''
bag hello soda this way
bag hello soda that way
something hello this foo this way
'''
model = mm.model_from_str(input)
assert len(model.lines) == 3
l = model.lines[1]
assert l.start == 'bag'
assert l.words == ['hello', 'soda']
assert l.command == 'that way'

有几点需要注意:

  • 您不必在重复中将[' ']指定为分隔符规则,因为默认情况下会跳过空格,
  • 要指定替代方案,请使用|
  • 您可以使用语法谓词!来检查是否有前方有东西,只有在没有时才继续。在规则Word中,这用于确保命令不会被Line规则中的Word重复使用。
  • 您可以通过为这些规则添加更多替代项来添加更多开始词和命令,
  • 如果您希望更加宽松并捕获命令,即使用户在命令词之间指定了多个空格(例如this way) 您可以使用正则表达式匹配或例如指定匹配,例如:
Command:
'this ' 'way' | 'that ' 'way';

这将匹配单个空格作为this的一部分,而不是在way之前任意数量的空格将被丢弃。

textX 网站上有一个包含示例的综合文档,因此我建议查看并浏览一些提供的示例。