【发布时间】:2017-01-23 00:26:08
【问题描述】:
我正在尝试编写一个词法分析器来解析如下所示的文件:
one.html /two/
one/two/ /three
three/four http://five.com
每行有两个用空格分隔的字符串。我需要创建两个正则表达式模式:一个匹配第一个字符串,另一个匹配第二个字符串。
这是我对词法分析器的正则表达式的尝试(一个名为 lexer.l 的文件将由 flex 运行):
%%
(\S+)(?:\s+\S+) { printf("FIRST %s\n", yytext); }
(?:\S+\s+)(\S+) { printf("SECOND %s\n", yytext); }
. { printf("Mystery character %s\n", yytext); }
%%
我在 Regex101 测试器中测试了 (\S+)(?:\s+\S+) 和 (?:\S+\s+)(\S+),它们似乎都工作正常:https://regex101.com/r/FQTO15/1
但是,当我尝试通过运行 flex lexer.l 来构建词法分析器时,我得到一个错误:
lexer.l:3: warning, rule cannot be matched
这是指我的第二条规则。如果我试图颠倒规则的顺序,我会再次收到第二个错误。如果我只遵守其中一条规则,它就可以正常工作。
我认为这个问题与两个正则表达式相似且长度相同这一事实有关,因此flex 认为它是模棱两可的,即使两个正则表达式捕获不同的东西(但它们匹配相同的东西?) .
我可以对正则表达式做些什么,以便它可以捕获/匹配我想要的内容而不会相互冲突?
编辑:更多测试示例
one.html /two/
one/two.html /three/four/
one /two
one/two/ /three
one_two/ /three
one%20two/ /three
one/two/ /three/four
one/two /three/four/five/
one/two.html http://three.four.com/
one/two/index.html http://three.example.com/four/
one http://two.example.com/three
one/two.pdf https://example.com
one/two?query=string /three/four/
go.example.com https://example.com
编辑
事实证明flex 使用的正则表达式引擎相当有限。它不能进行分组,而且它似乎也没有使用\s 作为空格。
所以这行不通:
^.*\s.*$
但这确实:
^.*" ".*$
感谢@fossil 提供的所有帮助。
【问题讨论】:
-
为什么不使用像
^(.*)\s(.*)$这样的单个表达式并在代码中使用匹配的组 -
@fossil 你的意思是用你的正则表达式匹配整行,然后用普通的C代码将它按空格分开吗?
-
正则表达式已经将它们分成两组。
-
@fossil 我刚刚尝试了你的正则表达式并且:(1)
yytext似乎包含两个字符串,(2)它无法匹配这个:one.html two/three -
测试字符串是什么?我会在本地查看。
标签: regex parsing flex-lexer lex text-parsing