3

这是我对堆栈提出的第一个问题,因为,好吧,我真的无法将我的大脑包裹在正则表达式上。我正在尝试操纵大学图书馆的高级目录搜索,以便在顾客搜索几种不同类别的材料类型中的“足球”之后,点击“修改您的搜索”按钮将它们返回到具有所有先前搜索参数的表单记得。这是一个古老的专有系统,因此默认情况下它会将顾客返回到搜索表单,但强制他们从头开始。

但是,位置字符串仍然具有所有参数,所以我想要做的是正则表达式并用 JS 填充表单。这是字符串的样子:

/search~S13/X?NOSRCH=(football)&m=i&m=g&m=r&m=r&m=1&m=5&m=g&m=o&m=7&m=j&m=i&m=2&m=3&m=q&m=m&SORT=D&SUBKEY=(football)

我想获取 m 的值,它的出现次数可能比上面的例子多很多。到目前为止,我正在这样做:

var str = location.search.match(/m.*?&/g);

返回

"m=i&", "m=g&", "m=r&", "m=r&", "m=1&", "m=5&", "m=g&", "m=o&", "m=7&", "m=j&", "m=i&", "m=2&", "m=3&", "m=q&", "m=m&"

您将如何仅获取iin的值m=i&

4

4 回答 4

1

我可以向您展示如何迭代字符串;你可能比我更了解 JavaScript,所以你知道如何从这些结果中创建一个数组:

var myregexp = /\bm=([^&]*)/g;
var match = myregexp.exec(subject);
while (match != null) {
    // matched text: match[1], add that to your result array
    }
    match = myregexp.exec(subject);
}

正则表达式的解释

\b      # Start at the beginning of an alphanumeric "word"
m=      # (in this case, it's just one letter) "m", followed by "="
(       # Match and capture in group number 1:
 [^&]*  #  any number of characters except ampersands
)       # End of capturing group.

据我所知,没有直接的方法来填充仅包含来自捕获组的匹配项的数组,而不是整个正则表达式的匹配项。

于 2013-01-30T15:40:53.723 回答
1

由于这是来自location.search您可以这样做:

location.search.substring(1).split('&').filter(function (e) {
    return /^m=/.test(e);
}).map(function (e) {
    return e.substring(2); 
});

第一种是从查询字符串中substring删除.?location.search

于 2013-01-30T17:33:21.350 回答
1

我可能误解了您的问题,但如果您使用的是 JavaScript,我认为 RegEx 是不必要的。

在任何情况下,首先,获取字符串的搜索部分并将问号从开头切掉,例如,

var str = window.location.search.slice(1);

然后,您可以使用 RegEx 路由或简单的 JavaScript 路由。

正则表达式:

使用非捕获和捕获组(在括号中)创建您的模式:

var regexPttrn = /(?:m\=)([^&=]+)/ig;

第一组用于?:查找字符m=。一旦找到它们,它就会捕获任何不是和号或等号的连续字符组。

不幸的是,您必须使用该exec方法来执行此操作,并且也在循环中,因为exec一次只匹配一个并且您需要在使用它之前检查返回的数组是否具有您需要的属性等。

JAVASCRIPT:

更好的是,不是使用 RegEx,而是str使用 & 符号作为分隔符,按照上面的定义将其拆分为不同属性的数组:

var arr = str.split('&');

所以这将创建一个字符串数组,例如"m=i","m=g"等。

arr然后通过运行一个循环并拆分使用等号作为分隔符的每个元素,将其中的每一个拆分为键值对:

var pairs = [];
for (var i = 0; i < arr.length; i += 1) {
    pairs[i] = arr[i].split("=");
}

这样,您将获得一个包含几个小数组的数组,其结构如下所示:

[
    [ "NOSRCH", "FOOTBALL" ],
    [ "m", "i" ],
    [ "m", "g" ],
    /* and so on, until... */
    [ "EY", "(football)" ]
]

要获取您的值,m您可以修改上面的循环以创建一个仅包含这些值的数组,如下所示:

var pairs = [],
    m_results = [];
for (var i = 0; i < arr.length; i += 1) {
    pairs.push(arr[i].split("="));
    if (pairs[i][0] === "m") {
        m_results.push(pairs[i][1]);
    }
}

然后该数组m_results将包含与m您的搜索字符串相关联的所有值。

总共只有 10 行代码,而且我认为比尝试一些受折磨的 RegEx 模式更容易评论、调试和重用,尽管我可以看到 RegEx 会更简洁,如果你能有效地捕获它。

于 2013-01-30T17:38:46.233 回答
0
var s = '/search~S13/X?NOSRCH=(football)&m=i&m=g&m=r&m=r&m=1&m=5&m=g&m=o&m=7&m=j&m=i&m=2&m=3&m=q&m=m&SORT=D&SUBKEY=(football)';
s.split(/&/).map(function(x) {
  return x.split(/=/);
}).filter(function(x) {
  return x[1] == 'i';
}); // => [['m', 'i'], ['m', 'i']]
于 2013-01-30T18:07:50.637 回答