2 回答

TA貢獻(xiàn)1847條經(jīng)驗(yàn) 獲得超11個(gè)贊
每個(gè)參數(shù)應(yīng)該只匹配一次。
是主要問題。
對(duì)于您的示例,我提出了以下正則表達(dá)式:
/abcd\s*\((?!(?:'[^']*'|[^')])*(?<=[\s(,])(name|count|id)(?=[\s=])(?:'[^']*'|[^')])*(?<=[\s,])\1(?=[\s=]))(?:(?<=[(,])\s*(?:name\s*=\s*'(?<name>[^']*?)'|count\s*=\s*'(?<count>[^']*?)'|id\s*=\s*'(?<id>[^']*?)')\s*[,)]){3}(?<=\))
它很長(zhǎng),所以讓我們分解一下。
/<function?name>\s*\(...(?<=\))
匹配函數(shù)名稱function name
、開頭(
(+ 斷言正則表達(dá)式以結(jié)尾結(jié)束)
)、可選空格(我不會(huì)在正則表達(dá)式的其余部分討論)和/
名稱前的 a。請(qǐng)注意,java 不需要轉(zhuǎn)義/
.
(?!...)
這是檢查沒有參數(shù)被多次使用的部分。將...
被一個(gè)子正則表達(dá)式替換,如果相同的值被使用兩次,該子正則表達(dá)式將匹配。子正則表達(dá)式是完整正則表達(dá)式的分解形式,用于模擬匹配的名稱-值對(duì)。
(?:'[^']*'|[^')])*
匹配(盡可能多)既不是也不是'
結(jié)束符的任何字符,或者)
匹配一個(gè)由 分隔且不包含的值。這將有效地讀取空格、逗號(hào)、等號(hào)和 argnames 以及完整的值。'
'
(?<=[\s(,])(<argname1>|<argname2>|...)(?=[\s=])
匹配任何參數(shù)名稱argname<n>
。還要檢查它是一個(gè)完整的名稱,而不僅僅是一個(gè)子字符串。(
如果名稱前有空格、逗號(hào)或空缺,則這是一個(gè)完整的名稱。完整名稱后是空格或=
.?匹配的 argname 存儲(chǔ)在捕獲組 1 中。請(qǐng)注意,此子正則表達(dá)式(在 中)以匹配任何(?!...)
名稱的方式編寫。因此它將嘗試匹配所有 argnames 并僅在沒有(no = not any)argname 被使用兩次時(shí)才接受。
(?:'[^']*'|[^')])*
同上。匹配每個(gè)字符或完整值。
(?<=[\s,])\1(?=[\s=])
將第一個(gè)捕獲組(任何 argname)的內(nèi)容重新匹配為完整名稱(名稱前的空格或逗號(hào),=
名稱后的空格或逗號(hào))。這是重要的部分。?這是第二次使用參數(shù)名稱的測(cè)試。
(?:(?<=[(,])\s*(?:...)\s*[,)]){<num?arguments>}
匹配num arguments
許多參數(shù)。每個(gè)參數(shù)必須以開頭(
(第一個(gè))或逗號(hào)(除第一個(gè)以外的所有內(nèi)容)開頭。此外,每個(gè)參數(shù)必須以逗號(hào)或結(jié)束符結(jié)尾)
。
包含...
參數(shù)規(guī)范和捕獲組的形式
<argname1>\s*=\s*'(?<argname1>[^']*)'|<argname2>\s*=\s*'(?<argname2>[^']*)'|...
其中 for 的值agname<n>
存儲(chǔ)在具有相同名稱的捕獲組中。Matcher
您可以使用 argname 作為組名從 java 中獲取該值。舉個(gè)例子matcher.group("count")
。

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超5個(gè)贊
如果要將選項(xiàng)與它們之間的逗號(hào)匹配,可以在 id 的值之后更改()
for ,并為結(jié)束參數(shù)添加一個(gè)額外的子句,
此正則表達(dá)式(與您的略有不同)將匹配括號(hào)之間的任意數(shù)量的參數(shù),以逗號(hào)和空格分隔
\/abcd\((id='[^']*', |name='[^']*', |count='[^']*', )*(id='[^']*'|name='[^']*'|count='[^']*')\)
您可以在這里試用regexr.com/4iqlu
編輯:將 .* 替換為 [^']*,因?yàn)槲覀円_保正則表達(dá)式不會(huì)在 '' 之外捕獲
添加回答
舉報(bào)