【问题标题】:how do i do a range regex in ruby like awk /start/,/stop/我如何在 ruby​​ 中执行范围正则表达式,例如 awk /start/,/stop/
【发布时间】:2012-10-10 10:29:18
【问题描述】:

我想做一个像这样的 AWK 风格的范围正则表达式:

awk ' /hoststatus/,/\}/' file

在 AWK 中,这将打印文件中两个模式之间的所有行:

hoststatus {
host_name=myhost
modified_attributes=0
check_command=check-host-alive
check_period=24x7
notification_period=workhours
check_interval=5.000000
retry_interval=1.000000
event_handler=
}

我如何在 Ruby 中做到这一点?

奖励:你会如何在 Python 中做到这一点?

这在 AWK 中确实很强大,但我是 Ruby 新手,不知道你会怎么做。在 Python 中我也找不到解决方案。

【问题讨论】:

    标签: python ruby regex awk


    【解决方案1】:

    鲁比:

    str =
    "drdxrdx
    hoststatus {
    host_name=myhost
    modified_attributes=0
    check_command=check-host-alive
    check_period=24x7
    notification_period=workhours
    check_interval=5.000000
    retry_interval=1.000000
    event_handler=
    }"
    str.each_line do |line|
      print line if line =~ /hoststatus/..line =~ /\}/
    end
    

    这是臭名昭著的flip-flop

    【讨论】:

    • @Tim Schaefer 这不是一个正则表达式,它是两个正则表达式作为活动的相互切换。 AFAIK Ruby 是从 Perl 那里偷来的,Perl 是从 AWK 那里偷来的。
    【解决方案2】:

    使用 python 将 multiline 和 dotall 标志传递给 re.这 ?跟随 * 使其不贪婪

    >>> import re
    >>> with open('test.x') as f:
    ...     print re.findall('^hoststatus.*?\n\}$', f.read(), re.DOTALL + re.MULTILINE)
    

    【讨论】:

    • 基本上和我的一样,(但可能会好一点)。尽管如此,这样做的缺点是您最终会一次读取整个文件,而不是像我假设的 awk 那样逐行读取。 (我打赌awk 也会更快地做到这一点:)
    • @mgilson,同意。我所知道的唯一可以使用完整的正则表达式功能进行多行匹配的工具,而不仅仅是指定范围的能力,并且无需将整个文件加载到内存中是 pcregrep。
    • 我无法完成这项工作。我一直在尝试很多变体,但仍然无法让它在 python 中工作。无论如何,谢谢...蒂姆
    • @mgilson:性能取决于很多因素,例如python greps for an ip in a file faster than awk(两个版本都不是为了速度而编写的)。目前尚不清楚什么更快(对于某些输入)re.findall() 或 awk 的触发器
    猜你喜欢
    • 2014-08-01
    • 2014-07-19
    • 2015-05-16
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    相关资源
    最近更新 更多