簡體   English   中英

正則表達式匹配一個額外的空組

[英]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:  ()

我的問題是:為什么? 如何解決? 實際的正則表達式是否有任何可能的改進?

演示jsFiddle

因為正則表達式匹配空字符串,所以您得到了最后一個假陽性匹配項:

"".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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM