Javascript 带模式的正则表达式字符串

Javascript 带模式的正则表达式字符串,javascript,regex,regex-group,Javascript,Regex,Regex Group,对于Regex的粉丝们。。。我拥有的是这个字符串: "Lorem ipsum dolor FOO IO BAR BA" 我想提取标题,以及大写后缀的数组: “Lorem ipsum dolor” [“FOO”、“IO”、“BAR”、“BA”] 以下是我的尝试: function retrieveGroups( string ) { var regexp = new RegExp(/(FOO|BAR|BA|IO)/g); var groups = string.match(

对于Regex的粉丝们。。。我拥有的是这个字符串:

"Lorem ipsum dolor FOO IO BAR BA"
我想提取标题,以及大写后缀的数组

  • “Lorem ipsum dolor”
  • [“FOO”、“IO”、“BAR”、“BA”]
  • 以下是我的尝试:

    function retrieveGroups( string )
    {
       var regexp = new RegExp(/(FOO|BAR|BA|IO)/g);    
       var groups = string.match( regexp ) || [];
       var title  = string.replace( regexp, "" );
       return {title:title, groups:groups};
    }
    
    结果:

    title  : "Lorem ipsum dolor    ",
    groups : ["FOO" , "IO", "BAR", "BA"]
    
    这很好,但不能防止这种情况:

    LoremFOO ipBAsum IO dolor FOO
    
    其中,在该cas中,我只需要结果组中的
    [“FOO”]

    规则似乎很简单

    获取标题
    标题可以全部大写(“LOREM IPSUM”)。
    获取大写后缀数组
    groups(FOO、BAR、IO、BA)可能不在字符串中。
    如果后缀不匹配,则不匹配:后缀且不以空格开头
    从字符串的末尾开始匹配(如果可能的话?),所以如果遇到重复的组参数,就不要匹配(上面的问题示例)

    我还尝试了
    string.replace(regexp,function(val)…
    ,但我不确定它有什么帮助


    不知道它是否有用,但是。谢谢!

    获取大写后缀数组

    > "Lorem ipsum dolor FOO IO BAR BA".match(/\b[A-Z]+\b(?!\s+\S*[^A-Z\s]\S*)/g)
    [ 'FOO',
      'IO',
      'BAR',
      'BA' ]
    > "LoremFOO ipBAsum IO dolor FOO".match(/\b[A-Z]+\b(?!\s+\S*[^A-Z\s]\S*)/g)
    [ 'FOO' ]
    
    获取标题数组

    > "LoremFOO ipBAsum IO dolor FOO".match(/^.*?(?=\s*\b[A-Z]+\b(?:\s+[A-Z]+\b|$))/g)
    [ 'LoremFOO ipBAsum IO dolor' ]
    > "Lorem ipsum dolor FOO IO BAR BA".match(/^.*?(?=\s*\b[A-Z]+\b(?:\s+[A-Z]+\b|$))/g)
    [ 'Lorem ipsum dolor' ]
    
    更新:

    > "LoremFOO ipBAsum IO dolor FOO".match(/\b(?:FOO|BAR|BA|IO)\b(?!\s+\S*[^A-Z\s]\S*)/g)
    [ 'FOO' ]
    
    • \b
      称为单词边界,匹配单词字符和非单词字符
    • (?:FOO | BAR | BA | IO)\b
      匹配
      FOO
      BAR
      BA
      IO
      以及以下单词边界

    • (?!\s+\s*[^A-Z\s]\s*)
      仅当后跟一个或多个空格字符、零个或多个非空格字符和除空格或大写字母以外的字符,且后跟零个或多个非空格字符时才有效。因此,对于
      IO
      ,此操作失败,因为它后跟的单词至少包含一个小写字母。
      (?!…)
      调用了负先行断言

    • > "LoremFOO ipBAsum IO dolor FOO".match(/\b(?:FOO|BAR|BA|IO)\b(?=\s+(?:FOO|BAR|BA|IO)\b|$)/g)
      [ 'FOO' ]
      

    此外,还可以使用基于正向前瞻的正则表达式。
    (?=…)
    称为正向前瞻断言

    > "LoremFOO ipBAsum IO dolor FOO".match(/\b(?:FOO|BAR|BA|IO)\b(?=\s+(?:FOO|BAR|BA|IO)\b|$)/g)
    [ 'FOO' ]
    

    获取标题数组。

    > "Lorem ipsum dolor FOO IO BAR BA".match(/^.*?(?=\s*\b(?:FOO|BAR|BA|IO)\b(?:\s+(?:FOO|BAR|BA|IO)\b|$))/g)
    [ 'Lorem ipsum dolor' ]
    > "LoremFOO ipBAsum IO dolor FOO".match(/^.*?(?=\s*\b(?:FOO|BAR|BA|IO)\b(?:\s+(?:FOO|BAR|BA|IO)\b|$))/g)
    [ 'LoremFOO ipBAsum IO dolor' ]
    

    也许这就是你想要的:

    function retrieveGroups( string )
    {
       var regexp = new RegExp(/^(.*?)\s*([ A-Z]+)*$/);    
       var result = string.match( regexp ) || [];
       var title  = result[1];
       var groups=result[2].split(" ");
       return {title:title, groups:groups};
    }
    
    编辑: 下面是一组固定大写单词的解决方案:

    function retrieveGroups( string )
    {
       var regexp = new RegExp(/^(.*?)\s*((?:\s|FOO|BAR|IO|BA)+)?$/);    
       var result = string.match( regexp ) || [];
       var title  = result[1];
       var groups=result[2].split(" ");
       return {title:title, groups:groups};
    }
    

    通过使用Avinash的正则表达式,可以提取所有有效的后缀。 标题将是第一个后缀之前的所有文本。 最后的JavaScript代码如下所示:

    var arr=['Lorem ipsum dolor FOO IO BAR BA','LoremFOO ipBAsum IO dolor FOO']
    arr.forEach(函数(str){
    var o=检索组(str);
    警报(“解析标题=“+o.title+”,组=“+o.groups”);
    });
    函数检索组(字符串){
    var regex=/\b(?:FOO | BAR | BA | IO)\b(?=\s+(?:FOO | BAR | BA | IO)\b |$)/g
    var groups=string.match(regex)| |[];
    var title=string.replace(正则表达式“”).trim();
    返回{'title':title,'groups':groups};
    
    }
    为什么不想匹配
    IO
    ?因为它不是后缀(因为后面有一些文本…),可能是标题的一部分。(我需要尽量减少错误)我想你不想要标题部分…@AvinashRaj感谢你的支持,是的,我还需要标题(现在添加到规则中,对不起).那么,第二个例子的标题部分是什么?很好!你能解释一下在最新的例子中你是如何设法不匹配
    IO
    的吗?如果可以的话,这只是一个附带的问题…如果我只有标题(全大写)但没有匹配规则(FOO-IO-BAR-BA),标题会在匹配中被捕获吗?这是我想避免的事情(这就是为什么我使用具有预定义匹配的组)thx作为回答我无法理解您的附带问题。哦,抱歉,所以,让我们假设字符串正好是:“LOREM IPSUM”。没有后缀。我想你的例子会把IPSUM作为后缀,但事实并非如此。后缀只能是FOO-BAR-IO-BAthen,这很简单。为什么你以前没有提到这一点?Guhh dunno真的很抱歉,所以基本上我只需要大写后缀,(其中4个,FOO-BAR-BA-IO)。后缀是可选的(可能根本没有后缀).Title可以是大写。我知道的是后缀前总是有一个空格。基本上就是这样。有什么想法吗?看起来很有希望,因为我可以看到
    s*
    *$
    的用法。让我测试一下!P.s当我作为旁注进行测试时,我想避免在结果数组中匹配大写标题…这可能吗?(这就是为什么我使用精确匹配的组
    BAR IO FOO BA
    )当您知道哪些大写单词可以在组中时,可以使用以下正则表达式:
    /^(.*)\s*(?:\s*(FOO | BAR | BAZ))*$/
    是的,我确切知道后缀参数是什么。其中只有4个是FOO-BAR IO-BA。您是否可以更新您的答案?您的评论中的正则表达式似乎很酷…太棒了…我已经在所有情况下测试了您的第二个示例,并猜出了什么。:)您是否尝试过:LoremFOO-ipBAsum IO-dolor(没有后缀的情况)这就是我使用Avinash的正则表达式的原因。谢谢,我也让他投票支持正则表达式。他的正则表达式只选择后缀,后面跟后缀或输入端。非常简单和整洁。是的,如果你参考Torben的答案,尽管你和Avinash都给了我一堂RegeExpzz的好课!!投了赞成票,非常感谢大家!!