Regexp,贪婪直到第二场比赛

时间:2013-09-10 10:36:47

标签: javascript regex

我正在尝试这样的事情

^(.*)[\s]*(?:\[[\s]*(.*)[\s]*\])?$

我的想法是,第一场比赛将返回所有内容,但偶尔会有第二场比赛,这是[]内的任何内容。要匹配的传入字符串已被修剪。

例如

'aaaaa [] [ddd]' -> returns 'aaaa []' plus 'ddd'
'[] [ddd]' -> returns '[]' plus 'ddd'
'aaaaaaaa' -> returns 'aaaaaaa' plus NULL
'aaaaaaaa []' -> returns 'aaaaaaa' plus ''
'aaaaaa [' -> returns 'aaaaaa [' plus NULL
'aaaa [] ddd' -> returns 'aaaa [] ddd' plus NULL
'[a] [b] [c] [d]' returns '[a] [b] [c]' plus 'd' instead of '' plus 'a] [b] [c] [d' 
'[fff]' -> return '' plus 'fff' <- That's particular since first match can never be null    

我的主要问题是由于第一场比赛,因为两者。*(吞下全部)和*? (只有多次吞下)才会产生不良结果

算法的伪代码类似于:

  • 如果最后一个字符是']',则第二个匹配将是内部的任何内容 最近的'['向后(如果存在) - &gt;如果输入,则可以为null或'' 字符串以'[]'
  • 结尾
  • Rest是第一个匹配,只能是NULL ''

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

如果没有嵌套,可以使用此正则表达式:

^(.*?)\s*(?:\[([^\]]*)\])?$

regex101 demo

否则,如果您可以在主[]中嵌套[],则必须修改正则表达式。您可以为嵌套[]创建一个正则表达式,但只能达到一定的嵌套级别;如果你有最多2级嵌套,你可以制作一个2的正则表达式,如果你有最多5个嵌套级别,你可以制作一个更复杂的嵌套级别,等等。

答案 1 :(得分:1)

我不确定你想要做什么但是,这是一个尝试:/(.*?)\[(.*?)\]$/

另一次尝试,允许第二组保持未定义:/(.*?)(?:\[(.*?)\])?$/

我从未使用过Scriptular,但这是Chrome的控制台所说的:

// result : [full match, group 1, group 2]
'abc'.match(/(.*?)(?:\[(.*?)\])?$/) // ["abc", "abc", undefined]
'[abc]'.match(/(.*?)(?:\[(.*?)\])?$/) // ["[abc]", "", "abc"]

这个怎么样:/(.*?)(?:\[([^\[]*?)\])?$/

'aze[[[rty]'.match(/(.*?)(?:\[([^\[]*?)\])?$/) // ["aze[[[rty]", "aze[[", "rty"]

上次尝试:/(.+?)(?:\[([^\[]*?)\])?$/

test         result
-------------------------------------------
''           null
'aze'        ["aze", "aze", undefined]
'[rty]'      ["[rty]", "[rty]", undefined]
'aze[rty]'   ["aze[rty]", "aze", "rty"]
'aze[]'      ["aze[]", "aze", ""]
'aze[][rty]' ["aze[][rty]", "aze[]", "rty"]
'aze[[]rty]' ["aze[[]rty]", "aze[", "]rty"]

答案 2 :(得分:1)

我认为正则表达式不是这里的答案,特别是因为你提供了一个简单的算法来解决问题。只需将算法转换为代码即可。

正则表达式也不是解决方案,因为您在注释中声明了不平衡和嵌套[],这使正则表达式变得不切实际。

试试这样的javascript:

function parse ( text ) {
    var first, inside;
    if ( text.substr (-1) == ']' ) {
        var pos = text.lastIndexOf ('[');
        first = text.substr (0, pos);
        inside = text.substr ( pos + 1, text.length -pos - 1);
    } else {
        first = text;
     }
     return [ first, inside ];
}