JavaScript正则表达式用于解析搜索参数

3
这是我在Stack上提出的第一个问题,因为我真的无法理解正则表达式。我正在尝试对大学图书馆的高级目录搜索进行调整,以便在读者在几个不同类别的材料类型中搜索“足球”后,点击“修改搜索”按钮会返回到具有先前所有搜索参数的表单。 它是旧的专有系统,所以它默认情况下会将读者退回到搜索表单,但强制要求他们从头开始。
但位置字符串仍然具有所有参数,所以我想做的是用正则表达式来填充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&"

你如何获取m = i&中的值i
4个回答

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 的查询字符串中删除 ?

1
我可能误解了你的问题,但我认为如果你使用JavaScript,正则表达式是不必要的。
无论如何,首先获取字符串的搜索部分并将问号从开头切掉,例如:
var str = window.location.search.slice(1);

Then you can either go the RegEx route or the simple JavaScript route. 接下来你可以选择使用正则表达式或简单的JavaScript方法。
REGEX: 使用非捕获组和捕获组(用括号表示)创建你的模式:
var regexPttrn = /(?:m\=)([^&=]+)/ig;

第一组使用?:查找字符m=。一旦找到它们,就会捕获任何连续字符组,这些字符不是&或等号。
不幸的是,你必须在循环内使用exec方法来完成此操作,因为exec一次只能匹配一个,你需要检查返回的数组是否具有所需属性,然后再使用它等等。
更好的方法是,不要使用RegEx,而是使用上面定义的ampersand作为分隔符将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行代码,比尝试某些扭曲的正则表达式模式更容易进行注释、调试和重用,尽管我可以看出如果您能有效地捕获它,正则表达式会更简洁。

以上所有的评论都很棒。感谢nhahtdh,因为出于某种原因我甚至从未考虑过location.search。无论如何,虽然有点晚了,但我想回复一下,我的最终做法是您的第二个建议:在感叹号后切割字符串并进行分割。 - mschofield

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.

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接