Javascript Match и RegExp Issue - Странное поведение - PullRequest
1 голос
/ 16 июля 2009

Я пытался использовать простую операцию jQuery для динамического сопоставления и сохранения всех тегов привязки и их текстов на странице. Но я обнаружил странное поведение. Когда вы используете match () или exec (), если вы определяете иглу как отдельный объект RegExp или переменную шаблона, тогда ваш запрос соответствует только одному экземпляру среди десятков в стоге сена.

И если вы назначите образец таким образом

match(/needle/gi) 

, тогда это соответствует каждому экземпляру иглы.

Вот мой код.

Вы даже можете запустить Firebug и попробовать этот код прямо здесь, на этой странице.

var a = {'text':'','parent':[]}; 

$("a").each(function(i,n) {

    var module = $.trim($(n).text());
    a.text += module.toLowerCase() + ',' + i + ','; 

    a.parent.push($(n).parent().parent()); 

});

var stringLowerCase = 'b';

var regex = new RegExp(stringLowerCase, "gi");
//console.log(a.text);
console.log("regex 1: ", regex.exec(a.text));

var regex2 = "/" + stringLowerCase + "/";
console.log("regex 2: ", a.text.match(regex2));

console.log("regex 3: ", a.text.match(/b/gi));

Для меня это возвращается:

regex 1:  ["b"]
regex 2: null
regex 3: ["b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b"]

Может кто-нибудь объяснить корень этого поведения?

EDIT : Я забыл упомянуть, что для regex1 не имеет значения, добавляете ли вы флаги "gi" для глобального и нечувствительного к регистру соответствия. Он по-прежнему возвращает только одно совпадение.

EDIT2 : Решил мою собственную проблему. Я до сих пор не знаю, почему один regex1 соответствует только одному экземпляру, но мне удалось сопоставить все экземпляры, используя match () и regex1.

Так что ... это соответствует всем и динамически!

var regex = new RegExp(stringLowerCase, "gi");
console.log("regex 2: ", a.text.match(regex));

Ответы [ 3 ]

4 голосов
/ 16 июля 2009

Это совсем не необычное поведение. В регулярном выражении 1 вы проверяете только 1 его экземпляр, тогда как в регулярном выражении 3 вы указали ему возвращать все экземпляры элемента с помощью аргумента / gi.

В Regex 2 вы предполагаете, что "/ b /" === / b /, когда это не так. "/ b /"! == / b /. «/ b /» - это строка, которая ищет, поэтому, если в вашей строке есть «/ b /», то она вернется, а / b / означает, что нужно искать между слешами, чтобы вы могли иметь «abc», и она будет возврат "b"

Надеюсь, это поможет.

EDIT:

Рассматривая это немного подробнее, методы exec возвращают первое найденное совпадение, а не все найденные совпадения.

EDIT:

var myRe = /ab*/g;
var str = "abbcdefabh";
var myArray;
while ((myArray = myRe.exec(str)) != null)
{
  var msg = "Found " + myArray[0] + ".  ";
  msg += "Next match starts at " + myRe.lastIndex;
  console.log(msg);
}

Посмотрев на него снова, он определенно вернет первый найденный экземпляр. Если вы пройдете через это, то вернетесь больше.

Почему это так? Понятия не имею ... мой JavaScript кунг-фу явно недостаточно силен, чтобы ответить на этот вопрос

2 голосов
/ 16 июля 2009

Причина, по которой регулярное выражение 2 возвращает null, заключается в том, что вы передаете "/ b /" в качестве параметра шаблона, в то время как "b" фактически является единственной вещью, которая фактически является частью шаблона. Косые черты являются сокращением для регулярных выражений, так же как [] для массива. Таким образом, если вы замените это просто новым регулярным выражением ("b"), вы получите одно совпадение, но только одно, так как в этом примере вы опускаете флаги "global + ignorecase". Чтобы получить одинаковые результаты для № 2 и № 3, измените соответственно:

var regex2 = stringLowerCase;
console.log("regex 2: ", a.text.match(regex2, "gi"));
console.log("regex 3: ", a.text.match(/b/gi));
0 голосов
/ 16 июля 2009

regex2 - это строка, а не RegExp, у меня тоже были проблемы с использованием такого синтаксиса, хотя я не совсем уверен в этом поведении.

Редактировать: Помните: для regex2 JS ищет "/ b /" как иглу, а не "b".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...