我想提取
来自下面提到的字符串的 "Memory: (71%)"
。这(71%)
每次都会改变。
字符串:"Memory: 327127123k. total, 2334437k used (71%), 9345624 k free (29%), 1123k buffers"
到目前为止,我已经制作了这个正则表达式,但它正在选择整行。
{[ regexp { Memory: (.*%)}
答案 0 :(得分:1)
首先,您必须在正则表达式中转义(
以使其与该字符匹配,因此:
{[ regexp { Memory: \(.*%\)}
这将匹配类似于
的字符串"Memory: (71%)"
然后,您需要考虑要捕获的百分比之前和之后的字符。有几种方法可以做到这一点,包括:
您可以使用组来捕获您感兴趣的子表达式,并允许Memory
和您的百分比之间的额外字符,所以:
{[ regexp { Memory:.*(\(.*%\))}
将找到一个包含Memory:
的字符串,后跟任意数量的以(XXXX5)
结尾的字符,其中X
是未确定的字符数,因此匹配{{1}之类的字符}但也可能是(71%)
。
您可以编码到您知道的更具体的上下文。当您知道要查找数字时,请不要使用通配符,所以也许
(ABC%)
在匹配组中只会找到一个或多个数字,后跟{[ regexp { Memory:.*\(\d+%\)}
。如果你知道你将有两个数字,请指定并获得更好的匹配:
%
或
`{[ regexp { Memory:.*\(\d\d%\)}`
两者都在寻找两位数。
最后,问一下为什么需要从字符串中提取`{[ regexp { Memory:.*\(\d{2}%\)}`
。您是否需要确保匹配的百分比仅来自这些行,表明文本中的其他行也有百分比?好的,您需要与Memory
匹配。但是,如果这些百分比仅在Memory
行中,则放弃该要求并使用简单的
Memory
将匹配任何包含两位数的括号,紧接着是`{[ regexp { \(\d{2}%\) }`
,
答案 1 :(得分:1)
正则表达式的关键是“我怎样才能使这个匹配只是我想要的部分?”并编写RE来处理这种情况。在这里,您要选择第一个单词,包括第一个冒号,跳过所有内容,直到之后的第一个括号,然后匹配并包括下一个括号。要记住的主要技巧是括号在用作文字时需要反斜杠,否则它们是RE元字符。
set str "Memory: 327127123k. total, 2334437k used (71%), 9345624 k free (29%), 1123k buffers"
if {[regexp {^([^:]*:)[^()]*(\([^()]*\))} $str -> a b]} {
puts "$a $b"
} else {
error "didn't match at all"
}
分解RE,有以下几个部分:
^
- 字符串锚的开始。因为这是一个好主意。(
[^:]
*
:
)
- 捕获第一个冒号的所有内容,即所有不是冒号然后冒号的内容[^()]
*
- 任意数量的非括号。(
\(
[^()]
*
\)
)
- 围绕任何非括号序列捕获括号。答案 2 :(得分:0)
set s "Memory: 327127123k. total, 2334437k used (71%), 9345624 k free (29%), 1123k buffers"
获取Memory: (71%)
:
format {Memory: (%s)} [regexp -inline {\d\d%} $s]
除非该行中的第一个单词发生更改,否则此(\d\d%
)就是您需要匹配和提取的全部内容。
如果非空格字符组的数量不变,您实际上甚至不需要正则表达式:
format {Memory: %s} [string trim [lindex $s 5] ,]
两种变体都给出了
Memory: (71%)
如果可能,请始终避免使用正则表达式匹配。
文档: format, lindex, regexp, string, Syntax of Tcl regular expressions