正则表达式字符串与模式

时间:2015-03-07 18:53:40

标签: javascript regex regex-group

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

"Lorem ipsum dolor FOO IO BAR BA"

我想提取大写后缀的标题数组

  1. "Lorem ipsum dolor"
  2. ["FOO", "IO", "BAR", "BA"]
  3. 这是我的尝试:

    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
    

    在那里,我在结果组中只需要["FOO"]

    规则似乎很简单......

    获取标题
    标题可以全部大写(" LOREM IPSUM") 获取一系列大写后缀
    字符串中可能不存在Grouops(FOO,BAR,IO,BA) 如果不是后缀,请不要匹配后缀:后缀并且不是由空格引导
    从字符串末尾开始匹配(如果可能?),以便在遇到时不要匹配重复的组参数(上面的例子)

    我也试过string.replace(regexp, function(val) ....,但我不确定它是如何帮助的......

    不知道它是否有帮助但fiddle is here。谢谢!

3 个答案:

答案 0 :(得分:3)

获取大写后缀的数组。

> "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匹配FOOBARBAIO以及以下字词边界

  • (?!\s+\S*[^A-Z\s]\S*)只有当后面没有一个或多个空格字符,零个或多个非空格字符以及空格或大写字母以外的字符时,再次跟随零或更多非空格字符。因此IO失败了,因为它后跟一个包含至少一个小写字母的单词。 (?!...)称为否定先行断言。


> "Lorem ipsum dolor FOO IO BAR BA".match(/\b(?:FOO|BAR|BA|IO)\b(?!\s+\S*[^A-Z\s]\S*)/g)
[ 'FOO',
  'IO',
  'BAR',
  'BA' ]

而且,你也可以使用正面的正则表达式。 (?=....)称为积极的先行断言。

> "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' ]

答案 1 :(得分:2)

也许这就是你要找的东西:

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};
}

答案 2 :(得分:2)

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

var arr = ['Lorem ipsum dolor FOO IO BAR BA', 'LoremFOO ipBAsum IO dolor FOO']

arr.forEach(function(str) {
  var o = retrieveGroups(str);
  alert("Parsed title = " + o.title + ", groups=" + o.groups);
});

function retrieveGroups( string ) {
  var regex = /\b(?:FOO|BAR|BA|IO)\b(?=\s+(?:FOO|BAR|BA|IO)\b|$)/g
  var groups = string.match( regex ) || [];
  var title  = string.replace( regex, '').trim();
  return {'title':title, 'groups':groups};
}

这是DEMO