首页 > 解决方案 > EXPECT 脚本中的正则表达式模式匹配

问题描述

我有一个监控 IBMIHS 服务器上的 http pid 的 EXPECT 脚本:

    ....
    send "ps -ef|grep htt|grep start|wc -l \r"
    expect {
       -re {.*(\d+).*} {

          set theNum $expect_out(1,string)
      }
    }

    puts "theNum = $theNum"

    if {$theNum > 8} {
      puts "it is ok"
    } else {
      puts "it is not ok"
    }
....

send "ps -ef|grep htt|grep start|wc -l \r"生成:

发送:发送“ps -ef|grep htt|grep start|wc -l \r”到 { exp5 }
'. (\d+)。' 是 ''。不可用,禁用性能增强器。

期望:“”(spawn_id exp5)是否匹配正则表达式“。(\ d +)。 ”?(无门,仅 RE)gate=yes re=no
ps -ef|grep htt|grep start|wc -l

期望: "ps -ef|grep htt|grep start|wc -l \r\n" (spawn_id exp5) 是否匹配正则表达式 ". (\d+). "?(No Gate, RE only) gate=yes re=no
11

期望: "ps -ef|grep htt|grep start|wc -l \r\n 11 \r\n" (spawn_id exp5) 是否匹配正则表达式 ". (\d+). "?(No Gate, RE only) gate=yes re=yes

期望:设置期望输出(0,字符串)“ps -ef|grep htt|grep start|wc -l \r\n 11 \r\n”
期望:设置期望输出(1,字符串)“1”
期望:设置期望输出( spawn_id) "exp5" expect: set expect_out(buffer) "ps -ef|grep htt|grep start|wc -l \r\n 11 \r\n"
theNum = 1
不行

命令行实际上返回一个数字“ 11 ”,但(\d+)捕获的是一个“1”

提前感谢您的意见。

标签: regexexpect

解决方案


这是由于前导的贪婪.*——因为这会吞下尽可能多的字符,所以该(\d+)部分剩余的文本是最后一个数字。这是一个演示,我还捕获了前导“。*”:

expect1.11> exp_internal 1
expect1.12> spawn sh -c {echo foo; echo 1234; echo bar}
spawn sh -c echo foo; echo 1234; echo bar
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {78523}
78523
expect1.13> expect -re {(.*)(\d+).*}
Gate keeper glob pattern for '(.*)(\d+).*' is ''. Not usable, disabling the performance booster.

expect: does "" (spawn_id exp10) match regular expression "(.*)(\d+).*"? (No Gate, RE only) gate=yes re=no
foo
1234
bar

expect: does "foo\r\n1234\r\nbar\r\n" (spawn_id exp10) match regular expression "(.*)(\d+).*"? (No Gate, RE only) gate=yes re=yes
expect: set expect_out(0,string) "foo\r\n1234\r\nbar\r\n"
expect: set expect_out(1,string) "foo\r\n123"
expect: set expect_out(2,string) "4"
expect: set expect_out(spawn_id) "exp10"
expect: set expect_out(buffer) "foo\r\n1234\r\nbar\r\n"

记下“1,string”和“2,string”中存储的内容

解决方案是简化您的正则表达式。如果您只想捕获第一组数字,请使用

expect -re {\d+}
set theNum $expect_out(0,string)

或者,如果您想捕获作为一行中唯一字符的第一个数字:

expect -re {\r\n(\d+)\r\n}
set theNum $expect_out(1,string)

这里的一个教训是,您通常不需要.*在正则表达式模式中使用前导通配符和结束通配符:只需关注捕获所需文本所需的内容即可。


推荐阅读