这个正则表达式试图在TCL中匹配什么

时间:2012-03-12 16:05:36

标签: regex tcl

我是正则表达式的新手,我试着理解以下正则表达式中的哪种字符串试图匹配:

set result [regexp "$PersonName\\|\[^\\n]*\\|\[^\\n]*\\|\\s*0x$PersonId\\|\\s*$gender" [split $outPut \n]]

上面的正则表达式试图匹配什么?结果的值是什么?

2 个答案:

答案 0 :(得分:2)

这里的复杂性是正则表达式规范受到Tcl的字符串插值规则的保护。

要解开思绪,你应该按照以下思路思考:

  1. "$PersonName\\|\[^\\n]*\\|\[^\\n]*\\|\\s*0x$PersonId\\|\\s*$gender"是双引号字符串,因此通常的插值规则适用:

    • 每个反斜杠都会转义以下字符;
    • 每个$variable引用都会替换其值;
    • [command ...]将替换已执行的command返回的字符串。

    因此\\的每次出现都会在插值字符串中产生一个'\'字符,\[意味着阻止Tcl将那些[^\n]解释为命令(命名) “^ \ n”)将被执行。

    因此,如果我们假设PersonName变量包含“Joe”,PersonId包含DEAD且gender包含“male”,则在执行所有替换后Tcl将获得Joe\|[^\n]*\|[^\n]*\|\s*0xDEAD\|\s*male在源字符串上。

  2. 现在生成的字符串被传递给RE引擎,RE引擎在分析表示正则表达式的字符串时应用自己的语法规则,如re_syntax manual page中所述。

    根据这些规则,每个反斜杠同样会逃避后面的字符,除非它是一个特殊的“字符输入转义”,所以我们在这里:

    • \s表示“任何空格字符”;
    • \|逃脱了'|'使它失去通常的意义 - 引入一个改变 - 使它与字符'|'字面匹配。

    [^\n]*构造意味着“不包括换行符的最长系列零个或多个字符”。阅读正则表达式中的“字符类”以获取更多信息。

答案 1 :(得分:0)

result的值将是正则表达式匹配的次数。如果没有-all选项,则始终为0或1(即未找到/找不到)。

总的来说,正则表达式(@ kostix的答案解释得很好)虽然很难看。 RE是一个强大的工具,但你可以很容易地与它们混淆。此外,如果您在换行符上拆分输出,那么您不需要尝试在RE匹配中排除它们;在这种情况下,肯定split的结果中没有新行。

如果我们更好地理解您要做的事情,我们可以指导您使用更有效的匹配方法(例如,使用lsearch和合适的选项,将数据加载到内存中的SQLite数据库中)。