如何匹配手動概要中特定形式的可選序列(包括變體)?

如何匹配手動概要中特定形式的可選序列(包括變體)?

問答有一個參考手冊頁概要「鬆散」地基於擴展巴科斯-諾爾範式元語法表示法。它很有趣並且可以作為背景。話雖這麼說,使用相關術語,您在手冊的命令概要中發現的最常見的元素類型之一是可選順序;由一個定義清單封閉在一個之間開始選項符號結束選項符號。在許多單字中,我們經常將其與類似的東西聯繫起來[ 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)匹配嵌套中所述[...]

相關內容