简体   繁体   English

JS正则表达式,用于捕获最后一组括号(不包括嵌套)

[英]JS Regex for Capturing Last Set of Parenthesis (Excluding Nested)

So I have found a few articles that talk about capturing what's inside a set of parenthesis, but can't seem to find one that specifically ignores nested parenthesis. 因此,我发现了几篇关于捕获一组括号内内容的文章,但似乎找不到专门忽略嵌套括号的文章。 Also, I would like to only capture the last set. 另外,我只想捕获最后一组。

So in essence there are three rules: 因此,从本质上讲,有三个规则:

  1. Capture text INSIDE of parenthesis 捕获括号内的文本
  2. Capture the content of only the LAST parenthesis 仅捕获LAST括号的内容
  3. Capture the content inside ONLY ONE SET of parenthesis (do not touch nesting) 仅在一组括号内捕获内容(请勿触摸嵌套)

Here are the 3 examples: 这是3个示例:

  • Pokemon Blue Version (Gameboy Color) should return Gameboy Color Pokemon Blue Version (Gameboy Color)应该返回Gameboy Color
  • Pokemon (International) (Gameboy Color) should return Gameboy Color Pokemon (International) (Gameboy Color)应该返回Gameboy Color
  • Pokemon Go (iPhone (7)) Should return iPhone (7) Pokemon Go (iPhone (7))应归还iPhone (7)

What would be the correct way of programming this in JS/jQuery ( .match() , .exec() )? 在JS / jQuery( .match() .exec() )中进行编程的正确方法是什么?

https://regex101.com/r/UOFxWC/2 https://regex101.com/r/UOFxWC/2

 var strings = [ 'Pokemon Blue Version (Gameboy Color)', 'Pokemon (International) (Gameboy Color)', 'Pokemon Go (iPhone (7))' ]; strings.forEach(function(string) { var re = /\\(([^)]+\\)?)\\)(?!.*\\([^)]+\\))/ig; var results = re.exec(string); console.log(results.pop()); }); 

Alternatively, you can parse the string yourself. 或者,您可以自己解析字符串。 The idea is to start from the back, each time you see ) add one to depth , subtract one if you see ( . When depth is > 0 , prepend the current character to a temporary string. Because you only want the final group, we can bail out ( break ) as soon as we have a full match, ie the sub string exists, and depth is back to zero. Note that this will not work with broken data: when the groups are not balanced you'll get odd results. so you have to make sure your data is correct. 这个想法是从后面开始,每次看到)depth加一个,如果看到( 。则减一。当depth > 0 ,将当前字符放在一个临时字符串的前面。因为只需要最后一组,我们可以在我们完全匹配后立即退出( break ),即子字符串存在,并且深度回到零。请注意,这不适用于中断的数据:当组不平衡时,您会得到奇怪的结果。,因此您必须确保数据正确无误。

 var strings = [ 'Pokemon Blue Version (Gameboy Color)', 'Pokemon (International) (Gameboy Color)', 'Pokemon Go (iPhone (7))', 'Pokemon Go (iPhon(e) (7))', 'Pokemon Go ( iPhone ((7)) )' ]; strings.forEach(function(string) { var chars = string.split(''); var tempString = ''; var depth = 0; var char; while (char = chars.pop()) { if (char == '\\(') { depth--; } if (depth > 0) { tempString = char + tempString; } if (char == '\\)') { depth++; } if (tempString != '' && depth === 0) break; } console.log(tempString); }); 

This is what I described in comments, feel free to define the behaviour you want when parenthesis are not balanced (if needed): 这是我在评论中描述的内容,当括号不平衡时(如果需要),可以随意定义所需的行为:

function lastparens(str) {
    var count = 0;
    var start_index = false;
    var candidate = '';

    for (var i = 0, l = str.length; i < l; i++) {
        var char = str.charAt(i);

        if (char == "(") {
            if (count == 0) start_index = i;
            count++;
        } else if (char == ")") {
            count--;

            if (count == 0 && start_index !== false)
                candidate = str.substr (start_index, i+1);

            if (count < 0 || start_index === false) {
                count = 0;
                start_index = false;
            }
        }
    }
    return candidate;
}

test cases: 测试用例:

var arr = [ 'Pokemon Blue Version (Gameboy Color)',
            'Pokemon (International) (Gameboy Color)',
            'Pokemon Go (iPhone (7))',

            'Pokemon Go ( iPhon(e) (7) )',
            'Pokemon Go ( iPhone ((7)) )',
            'Pokemon Go (iPhone (7)' ];

arr.forEach(function (elt, ind) {
    console.log( elt + ' => ' + lastparens(elt) );
} );

demo 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM