如何匹配手动概要中特定形式的可选序列(包括变体)?

如何匹配手动概要中特定形式的可选序列(包括变体)?

问答有一个参考手册页概要“松散”地基于扩展巴科斯-诺尔范式元语法表示法。它很有趣并且可以作为背景。话虽这么说,使用相关术语,您在手册的命令概要中发现的最常见的元素类型之一是可选顺序;由一个定义列表封闭在一个之间开始选项符号结束选项符号。在很多单词中,我们经常将其与类似的东西联系起来[ option ],例如,可以是一个单破折号或一个较长的双破折号形式,后面跟着一个或多个字符,例如在 中ps --help


所以我想匹配一个常见的可选序列模式,我们经常在手册中看到它确实:

  • 开始于[并结束于]
  • 包含一个可选序列形式-option--option
  • 不一定在括号内居中[-a],即 , [ -ab],[-abc ]全部匹配
  • 允许包含选项及其可选元素/说明符的列表,即[-a foo -b bar -c=biz end]
  • 允许其他括号出现在外部括号内,即[--a [-b[-c]] -d foo](将匹配此处的整个输入)

... 但允许:

  • ---任何情况下三破折号
  • 更清楚地说,像[option](没有破折号)和[], [-],[--][foo-bar=a]单独这样的东西不应该匹配。

数据不包含太多异常情况,例如上面提供的示例(我不知道如何交易也带有不匹配的括号,但这超出了本文的范围)。grep事后看来,尝试像我一样解决需求可能不是最好的主意,但我尝试过:

grep -E '\[{1,}([[:space:]]{0,}[[:punct:]]{0,}[[:alnum:]]{0,}){0,}(-{1,2}[[:alpha:]]{1,}){1,}([[:alnum:]]{0,}[[:punct:]]{0,}[[:space:]]{0,}){0,}\]{1,}'

它匹配了一些模式1,符合我想要的,但它有缺点,难以管理和重用。使用括号的任意集(3)对项目进行分组以管理匹配重复以创建“块”在这方面也没有帮助(但有助于调试)。使用角色类来迎合输入似乎是相当不可预测的。

那么如何使用更好的表达和/或不同的工具/方法来做到这一点呢?如果您使用如此长的正则表达式,您如何管理它们 - 在这种情况下您是否必须多次使用命令来过滤内容?我是否需要事先以不同的方式操作内容来帮助我解决这个问题?


1. 的输出迭代手册页文件提供了一个很好的测试机会。在这里,我使用了 grep:for i in /usr/share/man/man1/*.gz; do basename "${i//.1.gz}"; my_grep_command_above <<< "$(man -l "$i")"; done使用整个联机帮助页输出。否则man manman as提供了用于测试的可选序列的良好变体。

答案1

你可以这样做(使用 GNU grep):

grep -Po '\[\s*--?(?!-)((?>[^][]+)|\[(?1)*\])+\]'

您问题的正文中给出了:

[-a]
[ -ab]
[-abc ]
[-a foo -b bar -c=biz end]
[--a [-b[-c]] -d foo]

这个想法是使用 PCRE 及其递归匹配运算符,如pcrepattern(3)匹配嵌套中所述[...]

相关内容