我是正则表达式的新手,我试着理解以下正则表达式中的哪种字符串试图匹配:
set result [regexp "$PersonName\\|\[^\\n]*\\|\[^\\n]*\\|\\s*0x$PersonId\\|\\s*$gender" [split $outPut \n]]
上面的正则表达式试图匹配什么?结果的值是什么?
答案 0 :(得分:2)
这里的复杂性是正则表达式规范受到Tcl的字符串插值规则的保护。
要解开思绪,你应该按照以下思路思考:
"$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
在源字符串上。
现在生成的字符串被传递给RE引擎,RE引擎在分析表示正则表达式的字符串时应用自己的语法规则,如re_syntax
manual page中所述。
根据这些规则,每个反斜杠同样会逃避后面的字符,除非它是一个特殊的“字符输入转义”,所以我们在这里:
\s
表示“任何空格字符”; \|
逃脱了'|'使它失去通常的意义 - 引入一个改变 - 使它与字符'|'字面匹配。 [^\n]*
构造意味着“不包括换行符的最长系列零个或多个字符”。阅读正则表达式中的“字符类”以获取更多信息。
答案 1 :(得分:0)
result
的值将是正则表达式匹配的次数。如果没有-all
选项,则始终为0或1(即未找到/找不到)。
总的来说,正则表达式(@ kostix的答案解释得很好)虽然很难看。 RE是一个强大的工具,但你可以很容易地与它们混淆。此外,如果您在换行符上拆分输出,那么您不需要尝试在RE匹配中排除它们;在这种情况下,肯定在split
的结果中没有新行。
如果我们更好地理解您要做的事情,我们可以指导您使用更有效的匹配方法(例如,使用lsearch
和合适的选项,将数据加载到内存中的SQLite数据库中)。