【问题标题】:Pattern matching in a file文件中的模式匹配
【发布时间】:2016-07-17 04:24:07
【问题描述】:

Collocation -> n A m a k a (Collocation -> Words, Words -> Word Words, Word -> n A (Word -> Chars, Chars -> Char Chars, Char -> 'n', Chars -> Char, Char -> 'A'), Words -> Word Words, Word -> m a (Word -> Chars, Chars -> Char Chars, Char -> 'm', Chars -> Char, Char -> 'a'), Words -> Word, Word -> k a (Word -> Chars, Chars -> Char Chars, Char -> 'k', Chars -> Char, Char -> 'a'))

我有一个包含 1000 行这样的文件。我想搜索这样的模式 "Word -> n A (" 即,

  1. 应该以“Word ->”开头
  2. 之后它可以在任何情况下包含任意数量的字母
  3. 以左括号“(”结束

我想要的上面的例子,

  1. Word -> n A (
  2. 单词 -> m a (
  3. 单词 -> k a (

我试过这个 grep 命令: grep -no "Word -> .*(" 文件名

但是,它返回如下:

Word -> n A (Word -> Chars, Chars -> Char Chars, Char -> 'n', Chars -> Char, Char -> 'A'), Words -> Word Words, Word -> m a (Word -> Chars, Chars -> Char Chars, Char -> 'm', Chars -> Char, Char -> 'a'), Words -> Word, Word -> k a (

我还希望一行中的所有匹配模式都出现在输出文件的一行中。

还建议是否可以通过其他方法完成。

【问题讨论】:

    标签: regex grep


    【解决方案1】:
    $ grep -no 'Word -> [[:alpha:] ]\+(' file
    1:Word -> n A (
    1:Word -> m a (
    1:Word -> k a (
    

    上面显示了正则表达式匹配的原始文件中的行号。相反,如果您希望匹配按顺序编号,则:

    $ grep -o 'Word -> [[:alpha:] ]\+(' file | cat -n
         1  Word -> n A (
         2  Word -> m a (
         3  Word -> k a (
    

    原代码使用.*。这样做有两个问题。一个是. 匹配任何东西,包括(。第二个是正则表达式是贪心的:它匹配最长的匹配字符串。

    在这里,我们使用[[:alpha:] ]\+ 代替.*。这匹配一个或多个字母和空格。由于这只匹配字母和空格,它不会匹配(,因此匹配的长度将是您想要的。

    请注意,我们使用[:alpha:] 来匹配字母。与 [a-zA-Z] 等旧形式不同,[:alpha:] 是 unicode 安全的。

    使用.* 的问题在于它是贪婪的:它会匹配尽可能长的匹配。您似乎想要最短的匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 2017-10-19
      • 1970-01-01
      相关资源
      最近更新 更多