0

我有以下输出:

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

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

4

2 回答 2

0

即使您选择您声明的正则表达式来匹配多行,它也不会匹配超过您所说的第一次出现的内容,这是“RON_98”。它将在第一场比赛的最后一位数字之后停止。您甚至可以通过在 RegEx 末尾使用 $ 来强制它在读取一行后停止(匹配行尾)。

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

(RON)_\d*

更容易阅读。

于 2012-06-26T09:26:57.947 回答
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}]
    }
    

我通常建议使用第一个选项;它更容易使用!有时第二个更好,因为它提供更多信息并使用更少的中间存储,但要正确也更棘手。

于 2012-06-26T13:26:14.257 回答