【问题标题】:Regex string with pattern带模式的正则表达式字符串
【发布时间】:2015-03-07 18:53:39
【问题描述】:

对于正则表达式的粉丝......我拥有的是这个字符串:

"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

在那个案例中,我只需要结果组中的["FOO"]

规则看起来很简单……

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

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

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

【问题讨论】:

  • 为什么你不想匹配IO
  • 因为它不是后缀(因为它后面有一些文字......)并且可能是标题的一部分。 (我需要尽量减少错误)
  • 我认为你不想要标题部分...
  • @AvinashRaj 感谢您的支持,是的,我还需要标题(现在添加到规则中,抱歉)。
  • 那么,第二个例子的标题部分是什么?

标签: javascript regex regex-group


【解决方案1】:

获取大写后缀数组。

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

【讨论】:

  • 不错!您能否解释一下您是如何设法不匹配最新示例中的IO 的?如果我可以的话,只是一个附带问题......如果我只有标题(全部大写)但没有匹配规则(FOO IO BAR BA),标题会被匹配吗?这是我想避免的事情(这就是为什么我使用具有预定义 MATCHES 的组)thx 来响应
  • 我无法理解你的附带问题。
  • 哦,抱歉,假设字符串是:“LOREM IPSUM”。没有后缀。我认为您的示例会将 IPSUM 作为后缀,但事实并非如此。后缀只能是 FOO BAR IO BA
  • 那么就这么简单。为什么你之前没有提到这一点?
  • Guhhhh 不知道真的很抱歉,所以基本上我只需要获取大写后缀,(其中 4 个,FOO BAR BA IO)。后缀是可选的(可能根本没有后缀)。标题可以是大写。我所知道的是,总是有一个空格引导一个后缀。基本上就是这样。有什么想法吗?
【解决方案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};
}

【讨论】:

  • 看起来很有希望,因为我可以看到 s**$ 的使用。让我测试一下! PS当我作为旁注进行测试时,我想避免在结果数组中匹配大写标题......这可能吗? (这就是为什么我使用完全匹配的组BAR IO FOO BA
  • 当您知道哪些大写单词可以在组中时,您可以使用这个正则表达式:/^(.*?)\s*(?:\s*(FOO|BAR|BAZ))*$/
  • 是的,我确切地知道后缀参数是什么。只有 4 个 FOO BAR IO BA。你可以更新你的答案吗?您评论中的正则表达式似乎真的很酷......
  • 太棒了...我已经在所有情况下测试了你的第二个示例,你猜怎么着。 :) 谢谢
  • 您是否尝试过:LoremFOO ipBAsum IO dolor(没有后缀的案例)?这就是我使用 Avinash 正则表达式的原因。
【解决方案3】:

通过使用 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

【讨论】:

  • 谢谢,我也为正则表达式投了赞成票。他的正则表达式只选择那些后缀,后跟后缀或输入端。非常简单整洁。
  • 是的,如果您参考 Torben 的回答,尽管您和 Avinash 在 Regexpezz 中给了我很好的一课!点赞和感激。谢谢一群人!
猜你喜欢
  • 2015-11-28
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 2015-07-03
  • 2019-11-12
相关资源
最近更新 更多