Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Все возможные совпадения регулярному выражению (https://javascript.ru/forum/misc/10653-vse-vozmozhnye-sovpadeniya-regulyarnomu-vyrazheniyu.html)

Octane 14.07.2010 07:00

Все возможные совпадения регулярному выражению
 
Что-то я туплю и никак не пойму, как сделать, чтобы в следующем коде:
var str = "test test test", regexp = /test test/g;
while (regexp.exec(str)) {
    alert(regexp.lastIndex);
}

было найдено 2 совпадения «test test»?

Нужен именно exec в while, так как в каждой итерации используется lastIndex.

B@rmaley.e><e 14.07.2010 07:08

var str = "test test test", regexp = /test(?= test)/g;
while (regexp.exec(str)) {
    alert(regexp.lastIndex);
}
?

Octane 14.07.2010 07:32

Не получится так сделать, паттерн регулярного выражения из произвольного текста формируется, вложенные конструкции (?=) не будут же работать? И lastIndex нужен для конца подстроки, а не найденной части до (?=). Придется посимвольно перебирать?

var finder = {
	escape: function (str) {
		return str.replace(/([?!^$.(){}:|=[\]+\-\/\\*])/g, "\\$1");
	},
	createSearchPattern: function (text) {
		// В некоторых браузерах неразрывный пробел (&nbsp; или \u00A0) не попадает под облать действия метасимвола \s.
		// todo проработать остальные символы perfectionkills.com/whitespace-deviations
		return this.escape(text).replace(/^[\s\u0A00]+|[\s\u0A00]+$/, "").split(/[\s\u0A00]+/).join("[\\s\\u00A0]+");
	},
	find: function (text, search) {
		var regexp = new RegExp(this.createSearchPattern(search), "g");
		while (regexp.exec(text)) {
			alert(regexp.lastIndex);
		}
	}
};

finder.find("text text text", "text text");

subzey 14.07.2010 11:09

А вот такое не может пойти?
var str = "test test test", regexp = /test test/g;
while (regexp.exec(str)) {
    alert(regexp.lastIndex);
    /* что-нибудь полезное */
    regexp.lastIndex -= (RegExp['$&'].length - 1)
}

Riim 14.07.2010 12:43

Цитата:

Сообщение от subzey
$&

что-то новенькое. Что это?

B@rmaley.e><e 14.07.2010 12:46

Цитата:

Сообщение от Riim
что-то новенькое. Что это?

lastMatch. Вся совпавшая строка.
В опере 9 такого нет, про 10-ку не знаю в 10.6 есть.
alert( [/\d/.test('some text with 5 number'), RegExp.lastMatch, RegExp['$&']] );

subzey 14.07.2010 14:24

Ну, или так.
var str = "test test test", regexp = /test test/g;
var matches = [];
while (matches = regexp.exec(str)) {
    alert(regexp.lastIndex);
    /* что-нибудь полезное */
    regexp.lastIndex -= (matches[0].length - 1)
}
Надеюсь, общая мысль, без частности решения, понятна.

Octane 14.07.2010 19:39

Спасибо. Сделаю при помощи изменения lastIndex.

Octane 15.07.2010 05:51

Проверял поддержку RegExp.lastMatch в Opera, заработало в версии 10.53, в 10.10 нет, значит, скорее всего поддержку ввели в версии 10.50.


Часовой пояс GMT +3, время: 10:26.