我有以下输出:
Player name: RON_98
Player name: RON_97
player name: RON_96
我需要获取RON部分和后面的数字部分(例如98),我使用了以下正则表达式:regexp "(RON)_(\[0-9]*)"
,这是否与最后一行的RON_96相匹配? "*"
是贪心匹配,如何只匹配输出的第一行?我们有类似(RON)_(只匹配数字)吗?并且可以防止它与线的其余部分匹配?
答案 0 :(得分:0)
即使你选择你所陈述的正则表达式来匹配多行,它也不会超过你所说的第一次出现,这就是“RON_98”。它将在第一场比赛的最后一位数后停止。你甚至可以在你的RegEx结束时使用$来读取一行后强制它停止(匹配行尾)。
作为参考,[0-9]可以更容易地写成\ d(数字):
(RON)_\d*
更容易阅读。
答案 1 :(得分:0)
这在技术上并不是必需的(您可以使用Tcl的语言定义来精确计算出以任何其他方式执行此操作所需的反斜杠),但在您可能正常遇到的所有情况下都会更简单。
以下示例将使用此功能。
正则表达式会尽快开始匹配。然后,在正常(贪婪)的情况下,他们尽可能多地匹配文本。因此,使用示例代码和文本,匹配器开始尝试匹配第一行的R
,然后继续使用8
,此时它匹配并且停止。您可以通过要求regexp
将索引报告到匹配发生的字符串而不是匹配的子字符串(通过手册页上记录的-indices
选项)来验证这一点。
要获得所有字符串中的匹配项,您有两个选择:
将-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"
}
在-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}]
}
我通常建议使用第一个选项;它更容易使用!有时候第二个更好,因为它提供更多的信息并使用更少的中间存储,但是要做得更好也很棘手。