如何让我的正则表达式返回我的匹配?

时间:2014-11-07 18:03:28

标签: javascript regex

我这样做:

var regex = /^.*brainshark.*\/(?:vu\?pi=(.*)|.*-(\d*))/;

string.match(regex).exec()

假设字符串与正则表达式匹配,我得到一个三个数组。第一个元素包含整个字符串。第二个元素可能包含也可能不包含匹配,我的第三个元素可能包含也可能不包含匹配。

假设我的字符串是“http://my.brainshark.com/Public-Speaking-For-Executives-409829042”  我的比赛将在索引2上。

如果字符串为“http://www.brainshark.com/cvi/vu?pi=zF0z1327H2zC5iGz0”,则匹配将在索引1

我怎样才能得到它,以便我的匹配总是在元素1中,或者可能,我只是在没有任何数组的情况下取回我的匹配?

2 个答案:

答案 0 :(得分:2)

简短版本:在JavaScript中......你不能。

但是我们先得到一些术语:数组中的第一项是你的实际匹配。你得到整个字符串,因为你的模式碰巧匹配整个字符串。然后,每个捕获的组(模式中的括号)会得到一个项目。

不幸的是,JavaScript的正则表达式支持非常有限。其他口味可以让你轻松得到你想要的东西。例如:

  • Perl / PCRE支持branch reset group(?|vu\?pi=(.*)|.*-(\d*)) - 此模式将返回单个捕获组。
  • .NET支持重复的命名组:(?:vu\?pi=(?<id>.*)|.*-(?<id>\d*)) - 此模式将在id组中返回单个值。

但在JS中你基本上必须自己提取你的价值。一个简单的解决方案是:

var match = /your regex/.exec(yourString);
var value = match && (match[1] || match[2]);

作为旁注,我会像这样重写你的模式:

/^(?:https?:\/\/)?[^\/]*?brainshark.*\/(?:vu\b.*?[?&]pi=([^&]*)|.*-(\d*))/i

当您遇到包含更多查询参数的网址时,我使用了[^&]*[?&]。开头的更改是确保brainshark字符串在主机名中。哦,我还添加了不区分大小写。

答案 1 :(得分:0)

您在交替中定义了两个不重复的捕获组。因此,捕获组可以匹配子字符串,但不能同时匹配。这就解释了为什么你的匹配有时在索引1(第一个捕获组)和有时在索引2(第二个捕获组)中找到。

基本上,您有几个选择:

  1. 重写你的正则表达式,以便在交替周围只有一个捕获组。
  2. 将您的文字与现有表达式匹配,然后从两个捕获的值中选择一个。
  3. 写两个更简单的表达式,检查第一个是否匹配,如果不匹配,则执行第二个。
  4. 这里&#39;选项#2的外观如何:

    var matches = string.match(regex);
    var id = matches[1] || matches[2];
    

    但我会选择#1选项。