Это мой первый вопрос о стеке, потому что, ну, я просто не могу обернуть свой мозг в регулярные выражения. Я пытаюсь настроить расширенный поиск по каталогу в университетской библиотеке, чтобы после поиска, скажем, «футбола» по нескольким категориям типов материалов, нажатие кнопки «изменить поиск» возвращает их в форму со всеми их предыдущими параметрами поиска. вспомнил . Это старая, проприетарная система, поэтому по умолчанию она возвращает патрона в форму поиска, но заставляет их начинать с нуля.

Строка местоположения по-прежнему имеет все параметры, поэтому я хочу сделать регулярное выражение и заполнить форму 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&"

Как бы вы взяли только значение i в m=i&?

3
mschofield 30 Янв 2013 в 19:32

3 ответа

Лучший ответ

Возможно, я неправильно понял ваш вопрос, но я не думаю, что RegEx необходим, если вы используете JavaScript.

В любом случае, во-первых, возьмите поисковую часть строки и обрежьте знак вопроса с начала, например,

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

Затем вы можете пойти по маршруту RegEx или по простому маршруту JavaScript.

< Сильный > REGEX :

Создайте свой шаблон с группой без захвата и захвата (в скобках):

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 будет более лаконичным, если вы сможете заставить его эффективно захватывать.

1
guypursey 30 Янв 2013 в 19:40

Так как это из 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
nhahtdh 30 Янв 2013 в 17:33
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']]
0
maerics 30 Янв 2013 в 18:07