【问题标题】:How to grep multiple strings on same line in Ruby如何在Ruby中的同一行上grep多个字符串
【发布时间】:2016-10-17 15:07:35
【问题描述】:

如何将我的if 语句修改为 grep 在同一行中查找多个字符串?

string = "1.1.1.1 example.com"
if File.readlines("/etc/hosts").grep(/#{string}/).any?
    exit
else
    File.open("/etc/hosts", "w") { |file| file.write(host_file)}
end

这就是它在 bash 中的工作方式:

if grep -q "1.1.1.1 example.com";
  then
      exit
else
    echo "1.1.1.1 example.com" >> /etc/hosts
fi

【问题讨论】:

  • 我们希望看到更多尝试。你用什么string?为什么它不起作用?

标签: ruby regex


【解决方案1】:

我个人建议使用Resolv::Hosts 而不是手动解析主机文件。由于它内置在库中,因此它可以比您自己提出的任何方法更好地处理边缘情况。

它以 location of the hosts file on different systems 开头,然后是您有类似 1.1.1.1 example2.com example.com 的条目的情况,这些条目可以工作但与您的 grep 表达式不匹配。

【讨论】:

  • 请解释原因。
【解决方案2】:

从看“How to read lines of a file in Ruby”我认为你需要使用:

File.readlines('foo').each do |line|

为了读取文件中的所有行,然后对每一行执行 grep。

【讨论】:

    【解决方案3】:

    您的要求并不完全清楚,但从上下文来看,您似乎想要一个可用于搜索数组中多个条目的模式,因为 readlines 返回一个包含以下行的数组文件。

    一个简单的模式示例是:

    %w[foo bar baz].grep(/foo|bar/) # => ["foo", "bar"]
    

    | 表示“或”,因此模式/foo|bar/ 正在寻找"foo" or "bar"grep 将遍历数组 ['foo', 'bar'],并找到两者。

    这不是完整的解决方案,因为有龙在树林中等待。 /foo|bar/ 实际上是匹配子串,不是完整的单词:

    %w[food bartender].grep(/foo|bar/) # => ["food", "bartender"]
    

    这很可能不是你想要的。

    要解决这个问题,我们必须告诉正则表达式引擎只查找单词:

    %w[foo bar baz].grep(/\bfoo\b|\bbar\b/) # => ["foo", "bar"]
    %w[food bartender].grep(/\bfoo\b|\bbar\b/) # => []
    

    \b 表示“单词边界”,它是非单词字符和单词字符之间的转换。 \w 是使用的模式,它在the Regexp documentation 中定义。我强烈建议您阅读相关内容,因为您可能会遇到其他潜在问题。出于我们的目的,尽管\b 和默认行为可能没问题。

    虽然在那个小模式中有很多重复,但正则表达式让我们可以删除重复:

    %w[foo bar baz].grep(/\b(foo|bar)\b/) # => ["foo", "bar"]
    %w[food bartender].grep(/\b(foo|bar)\b/) # => []
    

    使用括号组 foo|bar 到一个捕获组中,因此周围的 \b 将应用于括号内的任何内容,从而减少噪音。

    有时您不想实际捕获字符串,而只想匹配它。如果是这种情况,请阅读文档中有关非捕获组的信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-09
      • 2018-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      相关资源
      最近更新 更多