Что означает [^]
Объясните, что означает в регулярных выражения выражение [^] ?
Выражение [/[^ab]+/ в строке 'abcde' говорит о том, что не нужно обращать внимание на ab или оно говорит, что ab должно использоваться в поиске, но не включатся в результат? |
[^ab]+ — "искать любые символы кроме a и b"
|
WorM32, Спасибо! Тогда получается, что в js регулярных выражений нет вовсе? Или я ошибаюсь?
Возможно, как-то сделать, чтобы я нашёл cde перед которыми обязательно идут ab? |
riva,
В JS есть регулярные выражения, но "смотрящих назад" условий нет. |
Цитата:
|
Цитата:
|
Цитата:
|
Цитата:
/ab(cde)/ Неожиданно, да? |
Цитата:
|
Цитата:
Цитата:
/(^|\n)"([\s\S]+)"($|\n)/ Спасибо Вам! |
Вот с чем работаю я -
var str = '"abc"de"\n'; Эту строку мне нужно распарсить по следующим условиям - Цитата:
var re = /(^|\n)"([\s\S]+)"($|\n)/ Получается, что третий элемент тот, что мне и был нужен. Цитата:
Цитата:
|
/(?:^|\n)"([\s\S]+)"(?:$|\n)/
/^"([\s\S]+)"$/m но это еще не конец)) '"abc"de"\n"abc"de"';)) ну допустим /^"([\s\S]+?)"$/m но все равно не идеал)) , тебе виднее как именно нужно сделать дальше. Из за отсутствия просмотра назад может придется еще что-то кроме регулярки делать. Хотя с \n^$ в этом плане проще, чем другими символами. По крайней мере в данном случае. |
Вообще если есть уверенность что первый символ точно ковычка, то можно извратиться так:
alert('"abc"de"\r\n"abc"deвак"'.match( /[^"\r\n]+.*(?="$)/mg )) |
Aetae , объясните пожалуйста выражение [^"\r\n].
А то я на него смотрю и понимаю, как - начать с кавычки, за которой идет перенос строки, но эти знаки не включать в результат. Так? Или они говорят - вообще не обращать внимания на эти символы и выводить все, кроме них самих? Это как бы и есть мой вопрос из-за которого я тему создал. |
riva, был же ответ:
Цитата:
^ - внутри квадратных скобок - отрицание. Как-то так, если упрощённо: " - не подходит под [^"\r\n]+, пропускаем a - подходит под [^"\r\n]+, начинаем получать результат b - подходит под [^"\r\n]+, берём c - подходит под [^"\r\n]+, берём " - не подходит под [^"\r\n]+, переходим к .*(?="$), подходит под .*(?="$), берём d - подходит под .*(?="$), берём e - подходит под .*(?="$), берём " - не подходит под .*(?="$) закончили первое совпадение \r - не подходит под [^"\r\n]+, пропускаем \n - не подходит под [^"\r\n]+, пропускаем " - не подходит под [^"\r\n]+, пропускаем a - подходит под [^"\r\n]+, начинаем получать результат b - подходит под [^"\r\n]+, берём c - подходит под [^"\r\n]+, берём " - не подходит под [^"\r\n]+, переходим к .*(?="$), подходит под .*(?="$), берём d - подходит под .*(?="$), берём e - подходит под .*(?="$), берём в - подходит под .*(?="$), берём а - подходит под .*(?="$), берём к - подходит под .*(?="$), берём " - не подходит под .*(?="$) закончили второе совпадение |
Цитата:
Цитата:
|
Ну нету в js regexp'ах просмотра назад, увы.
Так что придётся вам иметь дело с массивами:): alert('"abc"de"\n'.match( /^"(.*)"$/m )) |
Я пытаюсь комменты распарсить, но пока увы, безуспешно.
/** * Test-1 * Test-2 */ Вот так выглядит строка, если в файле только один коммент начатый с начала документа. '/**\n * Test-1\n * Test-2\n */' Пока остановился на ограничении количества звездочек, но ограничение в фигурных скобках у меня почему-то не работают.. |
alert( '/**\n * Test-1\n * Test-2\n */'.replace(/^\/\*\*\s+\*\s+/,'').replace(/\s*\*\/$/,'').split(/[\r\n]+\s\*\s/) ) |
Aetae, Спасибо! Но на Ваш пример, я пока только бегло глазами пробежал и всячески стараюсь от него убирать глаза. Я в js никогда не делал регуляки и мне хочется самому до этого дойти и во все разобраться, конечно с Вашей помощью.
У меня вот какой вопрос - как мне уже подсказали в это теме, если нужно из строки 'abcde' выбрать только символы 'cde', то нужно сделать так - /ab(cde)/ И тогда элемент под индексом один будет той строкой, которую и хотели получить. Но стоит включить флаг g, как все перестает работать. Как сделать, чтобы из строки выбрались только 'cde'? Желателньно какой-то универсальный вариант, так-как у меyz очень сложный пример. var str = 'abcde abcde'; var re = /ab(cde)/g; |
При флаге g в match - скобки игнорируются, ищет только полное вхождение строки.
Классическое решение: exec в цикле.(крайне рекомендую прочитать статью полностью) Ленивое решение - replace: var str = 'abcde abcde'; var re = /ab(cde)/g; var outArray = []; str.replace(re, function(matchedString, firstGroup, secondGroup){ outArray.push(firstGroup); }); alert(outArray); |
Aetae, Спасибо! Почитал...Но честно сказать не понял.
regexp = /a+(b+(c+))/g str = "abc aabbcc" Цитата:
И у меня ещё маленький вопрос, который я объясню на ужатой миниатюре. var str = 'DDD/**com m\nents*/ XXX /**comments*/III' var re = /\/\*{1,2}([\s\S]+)\*\//g; Строка иллюстрирует два блока комментариев с текстом между ними. Выражение, в моем понимании, означает следующее - выбрать все между слешом, после которого идет от одной до двух звездочек и звездачкой, после которого идет слеш. Цитата:
Возвращаясь к примеру... В первом случаи я наверное понял, хотя и могу ошибаться. Он находит 'abc' и начинает его разбирать дальше, 'bc', 'c'. Но если так, то почему во втором случаи он 'aabbcc', 'bbcc', то явно все начиналось с первой из двух 'a'/ И почему же он в следующий проход не вторую... Хотя я наверное понял!!! Он не строку гоняет, а выражение! Он начал с 'a+', потом 'b+' и затем 'c+'. Я прав? |
На счёт [\s\S]+ - множители(* +) по умолчанию жадные. Чтобы сделать поиск не жадным, нужно добавить в конец ?.
Если упростить: жадный продолжает поиск пока не находит совпадение максимально возможной длины, нежадный довольствуется самым первым. Под \S(не-пробел) подходит и b и с : alert([ 'abbbbbc'.match(/ab+\S/), //жадно 'abbbbbc'.match(/ab+?\S/) //нежадно ].join('\n')) |
Aetae, Спасибо! Ещё чуть-чуть и у меня получится:) Пишу чуть-чуть и смеюсь над этим, так-как каждый свой вопрос я сопровождаю мыслями, что получив на него ответ, я закончу. Но появляется новая проблема, которая сложнее и запутанней предыдущей. Вот и в этот раз так.
Чтобы было понятно, объясню полностью.. Вот какое выражение у меня получилось - var re = /(^|\n)(?=\/)\/(?=\*{1,2})(?!\*{3,})\*{1,}(?=\n{1,1})(?!\n{2,})\n([\s\S]+?)(?=\*)\*(?=\/)\/(?=\n|$)\n|$/g; Оно громоздкое, но по другому не как, ведь в комментариях может находится строка, которая содержит похожую на комментарии последовательность. Такой ситуации я лично никогда не встречал, но чтобы перестраховаться, сделал проверку на обязательную последовательность. Вот.. Вот имитатор самой строки - var str = 'DDDDDDDDDDD\n/**\n * IIIIIIIIIII\n * IIIIIIIIIII\n * \n */\nXXXXXXXXXXX\n\n/**\n * NNNNNNNNNNNNN\n * NNNNNNNNNNNNN\n */\nEEEEEEEEEEE\n'; И вот код цикла - var array = []; var result =[]; var isHasNext = true; while(isHasNext){ if(array = re.exec(str)){ result.push(array); }else{ isHasNext = false; } } console.log(result); И в ходе выполнения цикла, я получаю переполнение стека из-за того, что exec не возвращает null. Его глючит на - [ '', undefined, undefined, index: 121, input: 'DDDDDDDDDDD\n/**\n * IIIIIIIIIII\n * IIIIIIIIIII\n * \n */\nXXXXXXXXXXX\n\n/**\n * NNNNNNNNNNNNN\n * NNNNNNNNNNNNN\n */\nEEEEEEEEEEE\n' ] Почему так? Что с этим делать? Добавлено: Получилось! Спасибо Вам! Остался ещё один вопрос, но я сейчас поэкспериментирую и потом спрошу. |
У-уу, маньячина.)
|
Пока остановился на этом -
var re = /(^|\n)(?=\/\*\*\n)\/\*\*\n([\s\S]+?) \*\/(?=\n|$)/ Задам ещё один вопрос на этом выражении. Оно гласит - после начала строки или переноса строки, обязательно должно идти слеш и две звездочки, за которыми идет разрыв строки. И следом мне приходится опять писать эту же последовательность вне группы, чтобы исключить её из результата. И вопрос в том, можно и написать одновременно и обязательно и исключающи, чтобы не повторять одно и тоже дважды? У меня не получается так сделать... |
(?=\/\*\*\n) можно просто убрать, т.к. не несёт смысла. И снова: в js нет просмотра назад.
Для успокоения души рекомендую почитать о полноценных regexp, с их (?<=) и прочими плюшками. Возможно тогда вам таки удастся смириться с ограниченностью regexp в javascript и вы заметите, что совершенно необязательно решать все проблемы одной регуляркой, а можно просто написать небольшую функцию в несколько последовательных действий. |
Часовой пояс GMT +3, время: 15:30. |