Tcl 将正则表达式拆分为多行
Tcl split regex over multiple lines
我有一个很长的 RE 来匹配多个文件中的日期,我想把它分成多行,这样更容易阅读和更新。我将它设置为一个变量,然后在正则表达式语句中调用该变量。
set ::eval::regexdate { \d[\/\.-]\d{2}[\/\.-]\d{4}|\d{2}[\/\.-]\d{2}[\/\.-]\d{4}|\d{4}[\/\.-]\d{2}[\/\.-]\d{2}|(([12]\d|3[01])|([12]\d|3[01])(th|nd|rd|st))\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}|(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)[\/\.-]\d{2}[\/\.-]\d{4} }
然后我用下面的正则表达式行调用它...
if {[regexp "($::eval::regexdate)" $linefromfile all date]} {
Do something...
}
如果将 RE 设置为一个长字符串,这一切都可以正常工作,但如果我尝试使用 (?x) 将其分解为多行,如 post.
中所述
regexp pattern across multiple lines
set ::eval::regexdate {(?x)
\d[\/\.-]\d{2}[\/\.-]\d{4}|
\d{2}[\/\.-]\d{2}[\/\.-]\d{4}|
\d{4}[\/\.-]\d{2}[\/\.-]\d{2}|
(([12]\d|3[01])|([12]\d|3[01])(th|nd|rd|st))\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}|
(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)[\/\.-]\d{2}[\/\.-]\d{4}
}
我收到以下错误...
`couldn't compile regular expression pattern: quantifier operand invalid.`
我不确定为什么会这样,我的理解是使用 (?x) 会忽略所有白色 space 和注释,所以它应该只是将这些行拼接在一起以创建一个长的 RE,不?是“|”操作数导致我拆分 RE 的方式出现问题?
如果您能帮助我们弄清楚为什么在使用 (?x) 时它不起作用,我们将不胜感激。
谢谢
问题在于您在 regxep 命令中使用 regexdate 变量的方式。正如您引用的 post 所示, (?x)
应该位于正则表达式的开头。但是,通过使用 "($::eval::regexdate)"
,您可以在其两边加上括号,从而有效地构成表达式 ((?x)…)
。将完整的正则表达式用括号括起来不是很有用,因为 regexp 命令已经将完整匹配放在传递给它的第一个变量中。
因此,要么省略括号并使用完整匹配作为日期:
regexp $::eval::regexdate $linefromfile date
或将(?x)
移至电话:
set ::eval::regexdate {
\d[\/\.-]\d{2}[\/\.-]\d{4}|
\d{2}[\/\.-]\d{2}[\/\.-]\d{4}|
\d{4}[\/\.-]\d{2}[\/\.-]\d{2}|
(([12]\d|3[01])|([12]\d|3[01])(th|nd|rd|st))\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}|
(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)[\/\.-]\d{2}[\/\.-]\d{4}
}
if {[regexp "(?x)($::eval::regexdate)" $linefromfile all date]} {
Do something...
}
我有一个很长的 RE 来匹配多个文件中的日期,我想把它分成多行,这样更容易阅读和更新。我将它设置为一个变量,然后在正则表达式语句中调用该变量。
set ::eval::regexdate { \d[\/\.-]\d{2}[\/\.-]\d{4}|\d{2}[\/\.-]\d{2}[\/\.-]\d{4}|\d{4}[\/\.-]\d{2}[\/\.-]\d{2}|(([12]\d|3[01])|([12]\d|3[01])(th|nd|rd|st))\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}|(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)[\/\.-]\d{2}[\/\.-]\d{4} }
然后我用下面的正则表达式行调用它...
if {[regexp "($::eval::regexdate)" $linefromfile all date]} {
Do something...
}
如果将 RE 设置为一个长字符串,这一切都可以正常工作,但如果我尝试使用 (?x) 将其分解为多行,如 post.
中所述regexp pattern across multiple lines
set ::eval::regexdate {(?x)
\d[\/\.-]\d{2}[\/\.-]\d{4}|
\d{2}[\/\.-]\d{2}[\/\.-]\d{4}|
\d{4}[\/\.-]\d{2}[\/\.-]\d{2}|
(([12]\d|3[01])|([12]\d|3[01])(th|nd|rd|st))\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}|
(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)[\/\.-]\d{2}[\/\.-]\d{4}
}
我收到以下错误...
`couldn't compile regular expression pattern: quantifier operand invalid.`
我不确定为什么会这样,我的理解是使用 (?x) 会忽略所有白色 space 和注释,所以它应该只是将这些行拼接在一起以创建一个长的 RE,不?是“|”操作数导致我拆分 RE 的方式出现问题?
如果您能帮助我们弄清楚为什么在使用 (?x) 时它不起作用,我们将不胜感激。
谢谢
问题在于您在 regxep 命令中使用 regexdate 变量的方式。正如您引用的 post 所示, (?x)
应该位于正则表达式的开头。但是,通过使用 "($::eval::regexdate)"
,您可以在其两边加上括号,从而有效地构成表达式 ((?x)…)
。将完整的正则表达式用括号括起来不是很有用,因为 regexp 命令已经将完整匹配放在传递给它的第一个变量中。
因此,要么省略括号并使用完整匹配作为日期:
regexp $::eval::regexdate $linefromfile date
或将(?x)
移至电话:
set ::eval::regexdate {
\d[\/\.-]\d{2}[\/\.-]\d{4}|
\d{2}[\/\.-]\d{2}[\/\.-]\d{4}|
\d{4}[\/\.-]\d{2}[\/\.-]\d{2}|
(([12]\d|3[01])|([12]\d|3[01])(th|nd|rd|st))\s(January|February|March|April|May|June|July|August|September|October|November|December)\s\d{4}|
(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)[\/\.-]\d{2}[\/\.-]\d{4}
}
if {[regexp "(?x)($::eval::regexdate)" $linefromfile all date]} {
Do something...
}