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

Regex string with pattern

对于 Regex 爱好者...我有这个字符串:

"Lorem ipsum dolor FOO IO BAR BA"

我想提取 Title 和大写后缀的 Array

  1. "Lorem ipsum dolor"
  2. ["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")。
获取大写后缀数组.
组 (FOO,BAR,IO,BA) 可能不存在于字符串中。
如果不是,则不匹配后缀:后缀且不以 whitespace
开头 从字符串末尾开始匹配(如果可能?)所以如果遇到重复的组参数,请不要匹配(上面的问题示例)

我也试过 string.replace(regexp, function(val) .... 但我不确定它有什么帮助...

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

获取大写后缀数组。

> "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 称为单词边界,它匹配单词字符和 non-word 字符。
  • (?:FOO|BAR|BA|IO)\b 匹配 FOOBARBAIO 以及以下单词边界,

  • (?!\s+\S*[^A-Z\s]\S*) 仅当其后未跟一个或多个 space 字符、零个或多个 non-space 字符以及 [=57= 以外的字符时] 或大写字母,后跟零个或多个 non-space 个字符。所以这对于 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' ]

获取title数组

> "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 的 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