Регулярные выражения

Russian main discussion
  • Author
  • Message
Offline
Posts: 171
Joined: Thu Dec 01, 2011 11:15 pm
Location: Россия

Post by LonerD »

Можно ли одной операцией заменить несколько идущих подряд табуляторов на один табулятор И несколько идущих подряд пробелов на один пробел? Или это операция в два шага?

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

LonerD
Replace dialog, RegExp:
What: (\t| )\1+
With: \1

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

VladSh wrote:SearchReplaceEx.js слишком много телодвижений в этом случае.
Два хоткея + два клика мыши - это разве много?
Впрочем, если попросить автора скрипта, уважаемого KDJ, наверняка он поможет. Надо только сформулировать, что же в итоге требуется...

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Возник вопрос с переворачиванием текста вида

Code: Select all

1.655    172.20.2.250
63.185    172.20.3.229
к виду

Code: Select all

172.20.2.250    1,655
172.20.3.229    63,185
Сделал так:
что: (\d+)\.(\d+)([ \t]+)((\d{1,3}\.){3}\d{1,3})
чем: \4\3\1,\2
Оказалось, что числа могут быть отрицательными, но выражение

Code: Select all

(-?\d+)\.(\d+)([ \t]+)((\d{1,3}\.){3}\d{1,3})
заработало в Notepad++ и не заработало в AkelPad. Зато заработало

Code: Select all

(-?\d++)\.(\d+)([ \t]+)((\d{1,3}\.){3}\d{1,3})
А почему? Здесь же только числа в основном, жадность/сверхжадность вроде не должна иметь значение?
При этом поиск "^(-?\d+)" вполне работает.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

Skif_off
похоже, что употребление одной таблетки от жадности ? внутри захватывающей группы () лечит от жадности всё внутри группы, а не только ту часть, к которой относилась таблетка. Достаточно вынести таблетку за скобки, как всё снова начинает работать:

что: (-?)(\d+)\.(\d+)([ \t]+)((\d{1,3}\.){3}\d{1,3})
чем: \5\4\1\2,\3

На мой взгляд, это баг.

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Drugmix
Почему таблетка от жадности? Ведь тут использую ? как замену {0,1}. Хотя мысль, кажется, понял.
Раз выражение "^(-?\d+)" всё-таки работает как "^(-{0,1}\d+)", тогда да, наверное, баг.

Offline
Posts: 582
Joined: Mon Apr 08, 2013 9:50 pm
Location: Win7SP1x64, APx64

Post by Drugmix »

Skif_off
да, верно подмечено. Я не совсем точно выразился: жадность же бывает только у квантификаторов, а когда ? используется не после квантификатора, то он сам становится квантификатором ({0,1}).

А проблема, получается, несколько шире:
Skif_off wrote:Раз выражение "^(-?\d+)" всё-таки работает как "^(-{0,1}\d+)", тогда да, наверное, баг.
Бага не было бы, если бы всё именно так и работало бы. А оно как раз-таки работает не так и в этом и проблема.
Было справдливо замечено, что ?, идущий не после квантификатора, можно заменить на {0,1}.
Получается:

Code: Select all

(\-{0,1}\d+)\.(\d+)([ \t]+)((\d{1,3}\.){3}\d{1,3})
и оно тоже не работает.
И если указать более широкий диапазон ({0,1} заменить на {0,5}) - то тоже ничего не работает.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

Skif_off wrote:

Code: Select all

(-?\d+)\.(\d+)([ \t]+)((\d{1,3}\.){3}\d{1,3})
заработало в Notepad++ и не заработало в AkelPad.
Тестовая

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

В параллелной теме возник вопрос, полез ради любопытства и сломал голову. Например, как найти любое из чисел
128u
1024UL
1L
8Lu
?
Почему не находятся так:

Code: Select all

[0-9]+(ul|lu|u|l)
? Захватывается только первая буква из двух.
Можно попробовать так

Code: Select all

[0-9]+[ul]{1,2}
но найдутся и ошибочные "uu" и "ll".

-------------------
Instructor
Прошу прощения, сливал с телефона, потом забыл отписаться :(

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Skif_off wrote: Почему не находятся так:

Code: Select all

[0-9]+(ul|lu|u|l)
? Захватывается только первая буква из двух.
Попробуйте так:

Code: Select all

[0-9]+(?>ul|lu|u|l)

Offline
Posts: 294
Joined: Tue Jul 27, 2010 11:18 pm

Post by Serge Yolkin »

Skif_off
\b

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

YuS
Спасибо, так работает. А ведь таблицу в руководстве сначала прочитал :(

Serge Yolkin
Можно поподробнее? :) С \b были неожиданности, привык обходиться без.

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Skif_off wrote:YuS
Спасибо, так работает. А ведь таблицу в руководстве сначала прочитал :(
Здесь просто нет перебора вариантов (вернее он есть, но только вперед), поэтому удобнее использовать для данного случая, но, кстати, есть некоторая вероятность ошибки при поиске шаблона, которая исключается при использовании "\b":
Skif_off wrote: Serge Yolkin
Можно поподробнее? :) С \b были неожиданности, привык обходиться без.
т.к. \b - граница слова, то вариант:

Code: Select all

[0-9]+(?:ul|lu|u|l)\b
будет более правильным, хотя и менее скоростным...
Так тоже можно использовать:

Code: Select all

[0-9]+(?>ul|lu|u|l)\b

[0-9]+(?>ul|lu|u|l), найдет и такой текст:
128ubabc
а с шаблоном [0-9]+(?:ul|lu|u|l)\b, этот вариант будет исключен.

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Подскажите, пожалуйста, что не так с выражением

Code: Select all

^[^\r\n]++x64\.exe$
? Нужно найти строки вида "path\name-x64.exe", но не срабатывает ни в 4.9.6, ни в тестовой, зато срабатывает

Code: Select all

^[^\r\n]+x64\.exe$
разве что-то изменилось в поддержке регэкспов? Или туплю?

Добавлено:
Похоже, туплю - тут правильнее сделать нежадным "+?"?

YuS
Offline
Posts: 512
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Post by YuS »

Skif_off wrote:Подскажите, пожалуйста, что не так с выражением

Code: Select all

^[^\r\n]++x64\.exe$
? Нужно найти строки вида "path\name-x64.exe", но не срабатывает ни в 4.9.6, ни в тестовой, зато срабатывает

Code: Select all

^[^\r\n]+x64\.exe$
разве что-то изменилось в поддержке регэкспов?
сверхжадный шаблон захватывает максимально возможное количество символов и ничего уже не отдает, т.е. перебор вариантов отсутствует. В данном случае, шаблон

Code: Select all

^[^\r\n]++
захватывает целиком любую строку. Поэтому совпадений не будет найдено ни в одном из случаев, если после него в целом выражении будет ещё что-либо.

Жадный шаблон, захватывает максимально возможное количество символов, но с перебором вариантов, т.е. вот такая строка:

Code: Select all

abc path\name-x64.exe def path\name-x64.exe
будет захвачена полностью, а такая:

Code: Select all

abc path\name-x64.exe def path\name-x64.exe abcf
не будет захвачена вовсе.
Skif_off wrote: тут правильнее сделать нежадным "+?"?
А чтобы работал "ленивый" шаблон, необходимо убрать из выражения символ конца строки "$":

Code: Select all

^[^\r\n]+?x64\.exe
- в этом случае из строки:

Code: Select all

abc path\name-x64.exe def path\name-x64.exe abcf
будет захвачена только часть:

Code: Select all

abc path\name-x64.exe
Post Reply