Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   RegExp банально, нужно разрешить пробел между символами (http://www.flasher.ru/forum/showthread.php?t=213616)

caseyryan 22.11.2016 13:12

RegExp банально, нужно разрешить пробел между символами
 
Я что-то уже туплю. Написал за свою практику кучу регулярок, а тут тормознулся на такой мелочи
В общем, нужно распарсить html страницу, на которой есть списки со ссылками.
Так вот, есть ссылки вида <li><a href="/something/somethingelse/">Что-то</a>
Таких ссылок в коде страницы дофига, и все они ведут в подменю сайта. Нужно в мобильном приложении собрать это же меню с такой же структурой.
Загвоздка в том, что ссылки не всегда написаны именно так. Иногда там есть пробелы, любезно забытые разработчиком в php коде)
Собственно, ссылка иногда выглядит вот так: <li > <a href="/something/somethingelse/">
Пишу регулярку с look ahead и look behind
Код AS3:

var regExp:RegExp = /(?<=\<li><a href=\"\/)(.*?)(?=\<\/a><\/li>)/g;
var result:Array = pageText.match(regExp);

Она отлично находит ссылки первого вида (без пробелов).
А вот такая регулярка, находит второй вид
Код AS3:

var regExp:RegExp = /(?<=\<li > <a href=\"\/)(.*?)(?=\<\/a><\/li>)/g;

Видимо я действительно дико туплю и нужно пойти отдохнуть, но не могу придумать как в лук ахэд мне воткнуть любое количество пробелов
Код AS3:

var regExp:RegExp = /(?<=\<li\s*>\s*<a href=\"\/)(.*?)(?=\<\/a><\/li>)/g;

Такой вариант, не работает. Не работает так же если этот символ пробела обернуть в символьный класс или в диапазон

п.с. Доступа к исходному коду сайта нет

Zebestov 22.11.2016 14:45

А чем такая не подходит:
Код:

/(\<li\s*>\s*<a href=\"\/)(.*?)(\<\/a><\/li>)/g

i.o. 22.11.2016 18:44

Код AS3:

var re:RegExp = /<li\s*>\s*<a\s*href="(.+?)"/gim;
var input:String = ''
        + '<li><a href="/something/somethingelse/">Что-то</a>'
        + '<li >  <a href="/something/somethingelse2/">Что-то</a>'
        + ' \r\n <li  \n  > \r\n <a href="/something/somethingelse3/">Что-то</a>';
 
var matches:Array = [];
while (true) {
        var match:Array = re.exec(input);
        if (match) {
                matches.push(match);
        } else {
                break;
        }
 
}
 
var links:Array = matches.map(function(match:Array, index:int, arr:Array):String {
        return match[1];
});
 
trace(links.join("\n"));

На выходе:
Код:

/something/somethingelse/
/something/somethingelse2/
/something/somethingelse3/


caseyryan 23.11.2016 05:55

Цитата:

Сообщение от Zebestov (Сообщение 1197517)
А чем такая не подходит:
Код:

/(\<li\s*>\s*<a href=\"\/)(.*?)(\<\/a><\/li>)/g

Ну, тем, что мне нужно получить содержимое тегов, без самих тегов

i.o., вывод правильный, но как-то уж слишком мудрено. Есть вариант проще, сначала выполнить простую регулярку по сносу всех пробелов в тегах, а потом уже выполнить лукахэд и лукбехайнд. Что, я собственно и сделал.
Интересно почему не работает \s* в этих луках.
Код AS3:

var regExp:RegExp = /(?<=\<li><a href=\"\/)(.*?)(?=\<\/a>[\s]*)/g;
var result:Array = pageText.replace(/<li[\s>]+>*\s*<a /g, "<li><a ").match(regExp);

Вот так работает. Но если часть регулярки из replace перенести в lookahead, а replace убрать, работать перестанет. Похоже на баг.

i.o. 23.11.2016 10:04

Вот как раз с просмотром назад и вперед мудрено.
В твоей задаче нужно заматчить с группами все вхождения и потом по первой группе получить результат. С просмотрами назад получится в любом случае тормозная регулярка (это на будущее), хотя задачу выполняет абсолютно такую же.

Можно упростить до такого варианта
Код AS3:

var links:Array = [];
while (true) {
        var match:Array = re.exec(input);
        if (match) {
                links.push(match[1]);
        } else {
                break;
        }
 
}

Например в PHP есть preg_match_all(), может и в AS3 тоже есть что-то подобное...

Zebestov 23.11.2016 10:19

Цитата:

Сообщение от caseyryan (Сообщение 1197538)
Ну, тем, что мне нужно получить содержимое тегов, без самих тегов

В этом примере я просто избавился от lookbehind, чтобы поиск строки заработал. Остальное — вопрос одного движения, которое показал i.o. и его регулярка отлично работает, не мудри =)

caseyryan 23.11.2016 14:36

Цитата:

В этом примере я просто избавился от lookbehind, чтобы поиск строки заработал.
Так он и с lookbehind работает. Там, как я выяснил, вот такой символ \s* не правильно работает. Он нормально матчится, если есть хоть один пробел. Если пробелов нет, то матч не срабатывает. Хотя по идее должен, так как * как раз указывает на то, что никаких символов может и не быть
Цитата:

С просмотрами назад получится в любом случае тормозная регулярка (это на будущее), хотя задачу выполняет абсолютно такую же.
Регулярки, во всех языках, в которых я сними сталкивался, работают на удивление быстро. Можно даже ради интереса замерить скорость выполнения твоего варианта, и варианта с обратным просмотром.
В любом случае, спасибо за подсказку)

Zebestov 23.11.2016 14:41

Цитата:

Сообщение от caseyryan (Сообщение 1197546)
Так он и с lookbehind работает.

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

caseyryan 23.11.2016 17:18

Цитата:

Сообщение от Zebestov (Сообщение 1197547)
Ясно. Просто я думал, что какая-то заковыка именно в этом способе. А найденные онлайн-тулзы для теста регулярок на lookbehind ругаются, бо работают на JavaScript.

На сколько я знаю и в as3 до недавнего времени с ними были проблемы. Не работал или lookbehind или lookahead, точно не помню. А теперь работают оба, но, как выяснилиось, тоже не без багов)


Часовой пояс GMT +4, время: 20:29.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.