JavaScript中获取括号内字符串的正则表达式

267

我试图编写一个正则表达式,它可以返回括号中的字符串。例如,我想获取位于字符串“(”和“)”之间的字符串。

I expect five hundred dollars ($500).

会返回

$500

在Javascript中获取两个字符串之间的子字符串的正则表达式在这里

我不知道如何在正则表达式中使用'('和')'。


您可以使用 go-oleg 建议的解决方案,稍作修改以测试美元符号:var regExp = /\(\$([^)]+)\)/; - Dom Day
很高兴能看到你迄今为止尝试了什么。 - Scipion
10个回答

632
需要创建一组转义后的括号(用\进行转义),与原始括号匹配,以及一组常规括号来创建捕获组:

var regExp = /\(([^)]+)\)/;
var matches = regExp.exec("I expect five hundred dollars ($500).");

//matches[1] contains the value between the parentheses
console.log(matches[1]);

分解:

  • \( :匹配一个左括号
  • ( :开始捕获组
  • [^)]+:匹配一个或多个非右括号字符
  • ) :结束捕获组
  • \) :匹配一个右括号

RegExplained上有一种可视化的解释。


18
+1 很好,非常有效。我希望你能将这个链接http://tinyurl.com/mog7lr3添加到你的内容中,以便提供更形象化的解释。 - Praveen
9
如果括号中包含您想捕获的括号,这种方法就无法奏效,例如:“我期望五百美元($ 500(但我知道我再也见不到那笔钱了))”。 - JayB
6
只有在每个字符串匹配一个实例时,该正则表达式才能起作用。使用全局标志/g将不能按预期工作。 - silkAdmin
2
@IanWarburton,matches[0] 给出了完整的匹配字符串 '($500)',而 matches[1] 则只给出了捕获组中的内容。这里有更多关于 regExp.match() 返回值的信息。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec - sbru
9
如果您需要处理类似以下括号内有多个字符串的文本: “我期望(五)百美元($500)” 您可以使用正则表达式来匹配这些特殊字符串,并将它们存储在一个数组中。 - Mohamad Al Asmar
显示剩余10条评论

43

尝试字符串操作:

var txt = "I expect five hundred dollars ($500). and new brackets ($600)";
var newTxt = txt.split('(');
for (var i = 1; i < newTxt.length; i++) {
    console.log(newTxt[i].split(')')[0]);
}

或者正则表达式(相比上述方法有些


var txt = "I expect five hundred dollars ($500). and new brackets ($600)";
var regExp = /\(([^)]+)\)/g;
var matches = txt.match(regExp);
for (var i = 0; i < matches.length; i++) {
    var str = matches[i];
    console.log(str.substring(1, str.length - 1));
}

10
今天在Chrome 59.0.3071中运行那个jsperf时,正则表达式比以前快8%。 - Alex McMillan

25

简单解决方案

注意:此解决方案仅适用于只包含单个“(”和“)”的字符串,例如此问题中的字符串。

("I expect five hundred dollars ($500).").match(/\((.*)\)/).pop();

在线演示(jsfiddle)


2
如果匹配不存在,则在代码中添加可选链,这样将返回undefined而不是导致未捕获的异常。("我期望五百美元($500)。").match(/((.*))/)?.pop(); - dano

22

为了匹配括号内不包含任何内部括号的子字符串,您可以使用

\(([^()]*)\)

正则表达式。请参见正则表达式演示

在JavaScript中使用它的方式如下:

var rx = /\(([^()]*)\)/g;

模式细节

  • \( - 表示左括号 (
  • ([^()]*) - 捕获组1:一个否定字符类,匹配除了左右括号 () 之外的任何0个或多个字符
  • \) - 表示右括号 )

要获取整个匹配结果,请获取 Group 0 值,如果需要获取圆括号内的文本,请获取 Group 1 值。

最新的 JavaScript 代码演示(使用 matchAll):

const strs = ["I expect five hundred dollars ($500).", "I expect.. :( five hundred dollars ($500)."];
const rx = /\(([^()]*)\)/g;
strs.forEach(x => {
  const matches = [...x.matchAll(rx)];
  console.log( Array.from(matches, m => m[0]) ); // All full match values
  console.log( Array.from(matches, m => m[1]) ); // All Group 1 values
});

遗留的 JavaScript 代码演示(符合 ES5 标准):

var strs = ["I expect five hundred dollars ($500).", "I expect.. :( five hundred dollars ($500)."];
var rx = /\(([^()]*)\)/g;


for (var i=0;i<strs.length;i++) {
  console.log(strs[i]);

  // Grab Group 1 values:
  var res=[], m;
  while(m=rx.exec(strs[i])) {
    res.push(m[1]);
  }
  console.log("Group 1: ", res);

  // Grab whole values
  console.log("Whole matches: ", strs[i].match(rx));
}


2
这个正则表达式非常好,因为它只捕获成对的 () 及其内容,即使它们并排在一起 ()() 也可以。 - limitlessloop
2
@limitlessloop 既然这个答案看起来很有帮助,我也添加了一个基于 matchAll 的 JavaScript 代码演示。 - Wiktor Stribiżew
1
这个答案是最好的。 - GeminiYellow
如何包含括号,你能举个例子吗? - postgresnewbie
1
@postgresnewbie,它已经在那里了,console.log( Array.from(matches, m => m[0]) ); // All full match values。你不需要组,可以使用var rx = /\([^()]*\)/g; - Wiktor Stribiżew

13

为了避免使用临时全局变量,将Mr_Green的答案转化为函数式编程风格。

var matches = string2.split('[')
  .filter(function(v){ return v.indexOf(']') > -1})
  .map( function(value) { 
    return value.split(']')[0]
  })

1
我所需要的内容。https://stackoverflow.com/questions/49614116/how-to-get-all-sub-strings-inside-a-string-that-starts-with-and-end-with-a-chara?noredirect=1#comment86234810_49614116 - wobsoriano

8

替代方案:

var str = "I expect five hundred dollars ($500) ($1).";
str.match(/\(.*?\)/g).map(x => x.replace(/[()]/g, ""));

→ (2) ["$500", "$1"]

如果需要,可以用方括号或大括号代替括号。


str 没有括号时,这个东西就坏了。 - Ranjith Varatharajan

6

如果只需要货币符号后面的数字,可以使用\(.+\s*\d+\s*\)

或者对于括号内的任何内容,可以使用\(.+\)


3
这将适用于示例文本,但如果字符串中以后出现另一个 ")",例如 "我期望五百美元 ($500)。(但我要付款)",那么 "+" 的贪婪性会捕获更多内容。 - Ro Yo Mi
1
@Denomales,那么你如何捕获这些字符串的两个实例呢?理想情况下,我正在做类似的事情,但我希望能够将($500)(but I'm going to pay)分别匹配,而不是将它们视为单个匹配项。谢谢! - Tom Bird
1
(.+) 对我的需求起了作用。需要捕获像“Dunhill(瓶/包/罐/射)”这样的东西,并返回“Dunhill”。 - Ojchris

4

let str = "Before brackets (Inside brackets) After brackets".replace(/.*\(|\).*/g, '');
console.log(str) // Inside brackets


2
var str = "I expect five hundred dollars ($500) ($1).";
var rex = /\$\d+(?=\))/;
alert(rex.exec(str));

将匹配以$开头且后跟')'的第一个数字。 ')'不会成为匹配的一部分。 代码使用第一个匹配项进行警报。

var str = "I expect five hundred dollars ($500) ($1).";
var rex = /\$\d+(?=\))/g;
var matches = str.match(rex);
for (var i = 0; i < matches.length; i++)
{
    alert(matches[i]);
}

这段代码会提示所有匹配项。
参考资料:
搜索 "?=n" http://www.w3schools.com/jsref/jsref_obj_regexp.asp 搜索 "x(?=y)" https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp

0

简单易懂: (?<value>(?<=\().*(?=\)))

希望我能帮到你。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接