[英]Regular expression matches an extra empty group
我是正則表達式領域的新手。
我在下面發布的所有內容都是我的代碼中的簡化示例。
我有一個字符串,比如說test_1,some_2,foo,bar_4,
我想用title: test (1) title: some (2) title: foo () title: bar (4)
替換title: test (1) title: some (2) title: foo () title: bar (4)
我現在所擁有的(有效的)是:
var test = "test_1,some_2,foo,bar_4,";
console.log(test.replace(/(.*?)(?:_(\d))?,/g, "title: $1 ($2)\n"));
輸出:
title: test (1)
title: some (2)
title: foo ()
title: bar (4)
為了使事情變得正確,我想擺脫最后一個項目后的昏迷。 列表看起來像test_1,some_2,foo,bar_4
(bar_4之后沒有逗號)
所以新的代碼:
var test = "test_1,some_2,foo,bar_4";
console.log(test.replace(/(.*?)(?:_(\d))?(?:,|$)/g, "title: $1 ($2) "));
輸出錯誤。 最后還有一個空的比賽:
title: test (1)
title: some (2)
title: foo ()
title: bar (4)
title: ()
我的問題是:為什么? 如何解決? 實際的正則表達式是否有任何可能的改進?
因為正則表達式匹配空字符串,所以您得到了最后一個假陽性匹配項:
"".replace(/(.*?)(?:_(\d))?(?:,|$)/g, "title: '$1' ('$2') ");
title: '' ('')
因此,在您使用完所有字符之后,將匹配一個空字符串。
您可以通過將第一個組更改為非可選來進行控制,因為它實際上並不是一個可選的組,如圖所示。
/(.*?)(?:_(\d))?(?:,|$)/g
--^^--
例如,
var str = "test_1,some_2,foo,bar_4";
test.replace(/([a-z]+)(?:_(\d))?(?:,|$)/gi, "title: '$1' ('$2') ");
title: test (1) title: some (2) title: foo () title: bar (4)
那是,
([az]+)
: 至少匹配一個字母字符,並且 gi
:使字符串不區分大小寫。 作為最簡單的解決方案,您可以在匹配正則表達式之前將尾隨逗號添加到原始字符串。
您的問題是您的模式不僅匹配您想要的,而且匹配空字符串:
(.*?) # matches any string (including an empty one) not containing \n
(?:_(\d))? # it is an optional group
(?:,|$) # it matches a comma or the end of the string
因此,當您的正則表達式引擎根據模式評估字符串的結尾時,會看到:
因此整個模式都匹配,您將獲得額外的匹配。 您可以使用字符串的match
方法在控制台中清楚地看到它
> s.match(/(.*?)(?:_(\d))?(?:,|$)/g)
["test_1,", "some_2,", "foo,", "bar_4", ""]
您至少有兩個選擇來處理該問題:
replace
刪除不想要的部分返回的字符串 第一個選擇是優雅的選擇。 使用第二行代碼可以輕松實現第二個目標:
> var result = s.replace(/(.*?)(?:_(\d))?(?:,|$)/g, "title: $1 ($2) ");
> result = result.slice(0, result.lastIndexOf("title"));
"title: test (1) title: some (2) title: foo () title: bar (4) "
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.