如何匹配手動概要中特定形式的可選序列,包括變體?
在這個問答中,有一個參考手冊頁概要“鬆散地”基於元語法符號的擴展巴科斯-瑙爾形式。這很有趣,可以作為背景。話雖如此,使用相關術語,您會在手冊的命令概要中找到最常見的元素類型之一是可選序列;由包含在start-option-symbol和end-option-symbol之間的**定義列表組成。總而言之,我們經常將其與類似的東西聯繫起來,例如,可以是單個破折號或更長的雙破折號形式,後跟一個或多個字元,例如 in 。
[ option ]``ps --help
所以我想匹配我們經常在手冊中看到的一個常見的可選序列模式,它確實:
- 開始
[
和結束於]
- 包含形式為
-option
或的可選序列--option
- 不一定在括號內居中,即
[-a]
,[ -ab]
,[-abc ]
全部匹配- 允許包含選項及其可選元素/說明符的列表,即
[-a foo -b bar -c=biz end]
- 允許其他括號出現在外部括號內,即
[--a [-b[-c]] -d foo]
(將匹配此處的整個輸入)…但不允許:
---
任何情況下的三個破折號- 更清楚地說,像
[option]
(no dash) 和[]
,[-]
,[--]
or[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 man
,或man as
為測試提供一個很好的可選序列變體。
您可以(使用 GNU
grep
):grep -Po '\[\s*--?(?!-)((?>[^][]+)|\[(?1)*\])+\]'
在您的問題文本中給出:
[-a] [ -ab] [-abc ] [-a foo -b bar -c=biz end] [--a [-b[-c]] -d foo]
這個想法是使用 PCRE 及其遞歸匹配運算符,如
pcrepattern(3)
匹配嵌套中所述[...]
。