【问题标题】:Parsing of parenthesis with sed using regex使用正则表达式用 sed 解析括号
【发布时间】:2014-11-27 19:33:01
【问题描述】:

我在sed 中寻找一个命令来转换这个输入流:

dummy
(key1)
(key2)dummy(key3)
dummy(key4)dummy
dummy(key5)dummy))))dummy
dummy(key6)dummy))(key7)dummy))))

进入这个:

key1
key2
key3
key4
key5
key6
key7

其中dummy 可以是任何不带括号的字符串。所以我基本上想提取括号之间的字符串并每行输出一个字符串。可以有额外的右括号)

我使用正则表达式对sed 进行了许多测试,但我无法弄清楚 如何解决这个问题呢。虽然我确信这是可能的。 (我对 Perl 或 Python 等替代工具持开放态度)

编辑:括号之间的字符串 (key1, key2 .. key7) 可以是任何不带括号的字符串。

【问题讨论】:

  • cat input | perl -nle'print $1 if /(key\d+)/ 提问的时候也应该贴出你试过的代码!

标签: python regex perl sed


【解决方案1】:

在 Perl 中,您可以使用 Marpa,这是一个通用的 BNF 解析器——解析器代码在 this gist 中。

BNF 解析器可以说比正则表达式更易于维护。语法符号周围的括号将它们的值从解析树中隐藏起来,从而简化了后处理。

希望这会有所帮助。

【讨论】:

  • 谢谢,我去看看。
  • 太好了,顺便说一句,刚刚测试了 duxxmmy (test1) (k./\ey2)du./\mmy(ke3zb\.\/ouby3) du.\/\ddmmy(key44.\/\ 44)dum\/\/ffmy duddmmy(key55_[]-_55_5)dumppmy))))duaaammy dumrrmy(6key-_[].\/.6)drrummy))(key7)dddummy)))) 输出为 test1 k ./\ey2 ke3zb\.\/ouby3 key44.\/\44 key55_[]-_55_5 6key-_[].\/.6 key7
【解决方案2】:

我会这样做:

my @all_keys; 

while ( <DATA> ) {
   push ( @all_keys, m/\((.+?)\)/g  );
}
print join ("\n",@all_keys);


__DATA__
dummy
(key1)
(key2)dummy(key3)
dummy(key4)dummy
dummy(key5)dummy))))dummy
dummy(key6)dummy))(key7)dummy))))

这假定'keys' 与perlre 中的\w 匹配(字母数字加“_”,)

(如果您不熟悉 perl,您几乎可以将 &lt;DATA&gt; 替换为 &lt;STDIN&gt; 并将数据直接传送到您的脚本 - 或者使用 @all_keys 做更多有趣的事情)

【讨论】:

  • 我试过这个解决方案。事实上,它适用于字母数字字符串,但键字符串可以是任何不带括号的字符串,在我的例子中,我将使用它作为带有路径的文件名,这意味着它可以有特殊的字符,如 / \ 。 [ ] - _ 无论如何感谢您的宝贵时间,我创建了我的第一个 perl 脚本 ;-)
  • 您可以使用m/\((.+?)\)/g 进行更广泛的匹配 - . 表示任何字符类型,但使用? 进行最小匹配。请注意带有括号的文件名。
  • (答案已作相应修改 - 现在是否适用于您的示例数据?)
  • 它也确实有效。谢谢。 (看来我不能在左上角为两个答案打勾。我选择了最短的一个。)
  • 不用担心 - 多个有效答案不是坏事。如果它现在对您没有帮助,它可能会帮助稍后提出相同问题的人。
【解决方案3】:

您可以在grep -oP 中使用这个基于后视的正则表达式:

grep -oP '(?<=\()[^)]+' file
key1
key2
key3
key4
key5
key6
key7

或者使用awk:

awk -F '[()]' 'NF>1{for(i=2; i<=NF; i+=2) if ($i) print $i}' file
key1
key2
key3
key4
key5
key6
key7

【讨论】:

  • 谢谢。我选择你的解决方案。它适用于非常通用的字符串。事实上,我试过这个文件,它通过了:duxxmmy (test1) (k./\ey2)du./\mmy(ke3zb\.\/ouby3) du.\/\ddmmy(key44.\/\44) dum\/\/ffmy duddmmy(key55_[]-_55_5)dumppmy))))duaaammy dumrrmy(6key-_[].\/.6)drrummy))(key7)dddummy))))
  • 很高兴知道它成功了,您可以通过单击我的答案左上角的勾号将答案标记为已接受。
猜你喜欢
  • 2011-09-05
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-30
  • 2018-04-03
  • 1970-01-01
相关资源
最近更新 更多