正则表达式中的贪婪匹配

时间:2012-06-26 08:38:08

标签: regex tcl

我有以下输出:

Player name: RON_98
Player name: RON_97
player name: RON_96

我需要获取RON部分和后面的数字部分(例如98),我使用了以下正则表达式:regexp "(RON)_(\[0-9]*)",这是否与最后一行的RON_96相匹配? "*"是贪心匹配,如何只匹配输出的第一行?我们有类似(RON)_(只匹配数字)吗?并且可以防止它与线的其余部分匹配?

2 个答案:

答案 0 :(得分:0)

即使你选择你所陈述的正则表达式来匹配多行,它也不会超过你所说的第一次出现,这就是“RON_98”。它将在第一场比赛的最后一位数后停止。你甚至可以在你的RegEx结束时使用$来读取一行后强制它停止(匹配行尾)。

作为参考,[0-9]可以更容易地写成\ d(数字):

(RON)_\d*

更容易阅读。

答案 1 :(得分:0)

始终将正则表达式放在Tcl。

中的大括号中

这在技术上并不是必需的(您可以使用Tcl的语言定义来精确计算出以任何其他方式执行此操作所需的反斜杠),但在您可能正常遇到的所有情况下都会更简单。

以下示例将使用此功能。


正则表达式会尽快开始匹配。然后,在正常(贪婪)的情况下,他们尽可能多地匹配文本。因此,使用示例代码和文本,匹配器开始尝试匹配第一行的R,然后继续使用8,此时它匹配并且停止。您可以通过要求regexp将索引报告到匹配发生的字符串而不是匹配的子字符串(通过手册页上记录的-indices选项)来验证这一点。

要获得所有字符串中的匹配项,您有两个选择:

  1. -all -inline选项传递给regexp并使用foreach处理结果列表:

    # Three variables in foreach; one for whole match, one for each substring
    foreach {a b c} [regexp -all -inline {(RON)_([0-9]*)} $thedata] {
        puts "matched '$a', with b=$b and c=$c"
    }
    
  2. -indices循环中使用-start选项和while选项,以便逐步执行字符串:

    set idx 0
    while {[regexp -start $idx -indices {(RON)_([0-9]*)} $thedata a b c]} {
        puts "matched at '$a', with subranges '$b' and '$c'"
        set extracted [string range $thedata {*}$c]
        puts "the extracted value is '$extracted'"
    
        # Advance the place where the next search will start from
        set idx [expr {[lindex $a 1] + 1}]
    }
    
  3. 我通常建议使用第一个选项;它更容易使用!有时候第二个更好,因为它提供更多的信息并使用更少的中间存储,但是要做得更好也很棘手。