我遇到过以下材料:
re::debug
模块for perl 我也尝试使用其他各种技术:
Module re=debugcolor
突出了它的输出。
Used在构建?{print "$1 $2\n"}
之后。
但仍然没有明白如何阅读他们的输出。我还发现了另一个用于调试正则表达式here的模块但是我还没有尝试过它们,请你解释一下如何读取use re 'debug'
的输出或者用于调试正则表达式的其他命令Perl的?
编辑回复鲍罗丁:
第一个例子:
perl -Mre=debug -e' "foobar"=~/(.)\1/'
Compiling REx "(.)\1"
Final program:
1: OPEN1 (3)
3: REG_ANY (4)
4: CLOSE1 (6)
6: REF1 (8)
8: END (0)
minlen 1
Matching REx "(.)\1" against "foobar"
0 <> <foobar> | 1:OPEN1(3)
0 <> <foobar> | 3:REG_ANY(4)
1 <f> <oobar> | 4:CLOSE1(6)
1 <f> <oobar> | 6:REF1(8)
failed...
1 <f> <oobar> | 1:OPEN1(3)
1 <f> <oobar> | 3:REG_ANY(4)
2 <fo> <obar> | 4:CLOSE1(6)
2 <fo> <obar> | 6:REF1(8)
3 <foo> <bar> | 8:END(0)
Match successful!
Freeing REx: "(.)\1"
第二个例子:
perl -Mre=debugcolor -e' "foobar"=~/(.*)\1/'
Compiling REx "(.*)\1"
Final program:
1: OPEN1 (3)
3: STAR (5)
4: REG_ANY (0)
5: CLOSE1 (7)
7: REF1 (9)
9: END (0)
minlen 0
Matching REx "(.*)\1" against "foobar"
0 <foobar>| 1:OPEN1(3)
0 <foobar>| 3:STAR(5)
REG_ANY can match 6 times out of 2147483647...
6 <foobar>| 5: CLOSE1(7)
6 <foobar>| 7: REF1(9)
failed...
5 <foobar>| 5: CLOSE1(7)
5 <foobar>| 7: REF1(9)
failed...
4 <foobar>| 5: CLOSE1(7)
4 <foobar>| 7: REF1(9)
failed...
3 <foobar>| 5: CLOSE1(7)
3 <foobar>| 7: REF1(9)
failed...
2 <foobar>| 5: CLOSE1(7)
2 <foobar>| 7: REF1(9)
failed...
1 <foobar>| 5: CLOSE1(7)
1 <foobar>| 7: REF1(9)
failed...
0 <foobar>| 5: CLOSE1(7)
0 <foobar>| 7: REF1(9)
0 <foobar>| 9: END(0)
Match successful!
Freeing REx: "(.*)\1"
答案 0 :(得分:4)
正则表达式定义有限状态机 1 。调试器或多或少地向您显示状态机的进展情况,因为字符串是按字符消耗的。
&#34;编译REx&#34;是该正则表达式的说明列表。每个指令后括号中的数字是步骤成功后的位置。在/(.*)\1/
:
1: OPEN1 (3)
3: STAR (5)
4: REG_ANY (0)
5: CLOSE1 (7)
STAR (5)
表示计算STAR
,一旦成功,请转到指令5 CLOSE1
。
&#34;匹配REx&#34;是逐步执行这些指令。左边的数字是到目前为止消耗的字符总数。如果匹配器必须倒退,这个数字可能会下降,因为它尝试的东西都不起作用。
要理解这些说明,了解正则表达式如何工作非常重要。&#34;有限状态机通常可视化为一种流程图。我在/(.)\1/
下面制作了一个粗略的。由于对捕获组的反向引用,我不相信这个正则表达式是一个严格的有限状态机。该图表也很有用。
Match
+-------+ Anything +----------+
| Start +------------------+ State 1 |
+---^---+ +--+---+---+
| | |
| | |Matched same
+-------------------------+ | character
matched different |
character +----+------+
| Success |
+-----------+
我们从Start
开始。它很容易进入第一个状态,我们只消耗任何一个字符(REG_ANY
)。唯一可能发生的事情是输入结束。我还没有在这里画出来。 REG_ANY
指令包含在捕获组指令中。 OPEN1
开始将所有匹配的字符记录到第一个捕获组中。 CLOSE1
停止将字符记录到第一个捕获组。
一旦我们消费了一个角色,我们就坐在State 1
上并消耗下一个角色。如果它与之前的字符匹配,我们就会成功! REF1
是尝试匹配捕获组#1的指令。否则,我们失败了,需要回到Start
再试一次。只要匹配者说'#34;失败......&#34;它告诉你某些东西不起作用,所以它回到了一个早期的状态(可能包括也可能不包括“没有消耗的人物”)。
*
的示例更复杂。 *
(对应于STAR
)尝试将给定模式匹配零次或多次,并且 greedy 。这意味着它尝试匹配尽可能多的字符。从字符串的开头开始,它表示&#34;我最多可以匹配6个字符!&#34;因此,它匹配所有6个字符("foobar"
),关闭捕获组,并尝试再次匹配"foobar"
。这不起作用!它再次尝试5,这不起作用。依此类推,直到它尝试匹配零个字符。这意味着捕获组为空,匹配空字符串总是成功。所以匹配成功\1 = ""
。
我意识到我花了更多的时间来解释正则表达式,而不是使用Perl的正则表达式调试器。但是,一旦你理解了正则表达式如何运作,我认为它的输出会变得更加清晰。
这是finite state machine simulator。您可以输入正则表达式并查看它是否已执行。不幸的是,它不支持反向引用。
1:我相信Perl的一些正则表达式功能超越了这个定义,但以这种方式思考它们仍然很有用。
答案 1 :(得分:2)
调试信息包含字节码的描述。数字表示操作树中的节点索引。圆括号中的数字表示引擎在匹配时跳转到特定节点。 EXACT运算符告诉正则表达式引擎查找文字字符串。 REG_ANY表示。符号。 PLUS表示+。代码0用于'结束'节点。 OPEN1是'('符号.CLOSE1表示')'。 STAR是'*'。当匹配器到达结束节点时,它会将成功代码返回给Perl,表明整个正则表达式已匹配。
在http://perldoc.perl.org/perldebguts.html#Debugging-Regular-Expressions和更具概念性的http://perl.plover.com/Rx/paper/
上查看更多详情