【问题标题】:Tcl split regex over multiple linesTcl 在多行上拆分正则表达式
【发布时间】:2023-03-22 09:29:01
【问题描述】:

我有一个很长的 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) 将其拆分为多行。

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) 会忽略所有空白和 cmets,因此它应该将这些行重新缝合在一起以创建一个长 RE,不是吗?是“|”操作数导致我拆分 RE 的方式出现问题?

任何帮助都将不胜感激,以找出为什么在使用 (?x) 时它不起作用。

谢谢

【问题讨论】:

    标签: regex tcl


    【解决方案1】:

    问题在于您在 regxep 命令中使用 regexdate 变量的方式。正如您引用的帖子所示,(?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...
    }
    

    【讨论】:

    • 还要注意两个正则表达式并不完全等价。你的单线在两端都有一个空间。多行版本不是这种情况。根据提供的信息,无法判断这些空格是否是故意的。
    • 感谢 Schelte,将 (?x) 移到通话中起到了重要作用。我想我对它应该放在哪里感到困惑。不在变量中,而是在正则表达式行本身中。简单的修复,嗯? ! :) 非常感谢。
    • 如果将变量与其他内容结合起来,只要将 (?x) 放在变量中,它就可以放在正则表达式的开头。
    猜你喜欢
    • 2020-03-30
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-29
    • 1970-01-01
    相关资源
    最近更新 更多