Привет камрадам! Есть такое регулярное выражение - s/((\w|\A)\w+)(\w+)/\L$1$2/ Данная конструкция делает следующее: при помощи оператора связывания (=~) можно переобразовать в строке все буквы из прописных в строчные. Данный regexp нашел "методом проб и ошибок" и по этому могу его неправильно понимать. Собственно, прилагаю свой комментарий и хотелось бы "услышать" объяснение от камрадов :). Итак... - конструкция s/// - "подстановка" того, что находится между первым и вторым слэшами на то, что находится между вторым и третьим слэшами. - выражение ((\w|\A)\w+)(\w+) - найти любой алфавитно-цифровой символ \w в начале \A строки и найти дальше один или более алфавитно-цифровых символов и еще один любой алфавитно-цифровой. Хотя тут непонятно до конца. Символ | дизъюнкции выполняет "перебор" шаблонов между "пайпом". Но без него не работает regexp в данном случае. - выражение собственно замены \L$1$2 выполняет глобальную замену прописных букв на строчные. Снова заминка :) . Назначение переменных $1 and $2 непонятна. В учебнике сообщается, что переменная $1 хранит место где нужно заменить символ, а переменная $2 хранит сам символ. Как в таком случае понимать ситуацию с несколькими символами? Где они "хранятся"? Ведь переменные $1 $2 - это скаляры и значит там более чем одного литерала просто нет... А может я что-то еще не понимаю :( Вообщем, камрады прокомментируйте. Спасибо

Возможно я не
Возможно я не совсем правильно понял вопрос.
Конечной целью является изучение regexp или выполнение какой-либо задачи?
Если второе, то можно уточнить желаемый конечный результат? Перевести все символы в нижний регистр?
Что до $1 и $2 то они содержат найденный текст, заключенный в скобки.
Т.е. в данном случае $1 примет значение, соответствующее ((\w|\A)\w+) а $2 - (\w|\A). $3
будет содержать оставшийся (\w+), который в примере теряется.
Таким образом, вторая часть выражения заменит в найденном слове последний символ на первый и приведет все к нижнему регистру.
to korshak Цель
to korshak
Цель глобальная - изучение regexp :)
Цель для данного regexp-a - да, перевод всех символов строки в нижний регистр
Хмм. Прошу
Хмм. Прошу прощенья, в предыдущем комментарии и я допустил грубую ошибку.
Перл "раскладывает" вложенные скобки таким образом переменные
$1, $2, $3 будут соответствовать захвату
$1 - ((\w|\A)\w+)
$2 - (\w|\A)
$3 - (\w+)
По крайней мере для perl версии 5.8.8 Я несколько смущен этим фактом.
Возможно кто-то может прокомментировать, было ли так в предыдущих версиях perl,
или это изменение сделано относительно недавно. Я действительно смущен.
Таким образом конструкция s/((\w|\A)\w+)(\w+)/\L$1$2/ заменит последний символ "слова"
на первый символ этого же слова и приведет результат к нижнему регистру.
Some => soms
А в общем для приведения к нижнему регистру мне больше нравится использовать lc() :)
...
$a = "";
for(0..127) # формируем тестовый массив (строку)
{
$a = $a . chr($_); # ASCII - т.е. от 0 до 127
}
# ВАРИАНТ 2 - ЗАМЕНЯЕМ СИМВОЛЫ ИХ
# ШЕСТНАДЦАТЕРИЧНЫМИ КОДАМИ
$a =~ s/([\x00-\xFF])/sprintf("%02X ", ord($1))/gie;
print $a;
# обратите внимание на то, что в регулярке вызывается ф-ция!
# --- привет камрадам! ---
Ну про lc() -
Ну про lc() - знамо дело... Нужно было реализовать именно средствами regexp :)
Не понял
for(0..127) # формируем тестовый массив (строку)
{
$a = $a . chr($_); # ASCII - т.е. от 0 до 127
}
# ВАРИАНТ 2 - ЗАМЕНЯЕМ СИМВОЛЫ ИХ
# ШЕСТНАДЦАТЕРИЧНЫМИ КОДАМИ
$a =~ s/([\x00-\xFF])/sprintf("%02X ", ord($1))/gie;
print $a;
# обратите внимание на то, что в регулярке вызывается ф-ция!
# --- привет камрадам! ---
Хм... не понял. А к чему был пример? Сокровенный смысл какой?
Недогнал :)
Did not seem
Перл "раскладывает" вложенные скобки таким образом переменные
$1, $2, $3 будут соответствовать захвату
$1 - ((\w|\A)\w+)
$2 - (\w|\A)
$3 - (\w+)
По крайней мере для perl версии 5.8.8 Я несколько смущен этим фактом.
Возможно кто-то может прокомментировать, было ли так в предыдущих версиях perl,
или это изменение сделано относительно недавно. Я действительно смущен.
Таким образом конструкция s/((\w|\A)\w+)(\w+)/\L$1$2/ заменит последний символ "слова"
на первый символ этого же слова и приведет результат к нижнему регистру.
Some => soms
А в общем для приведения к нижнему регистру мне больше нравится использовать lc() :)
А про замену последнего символа на первый - это точно. Просто я весь этот регэксп тестировал на палиндроме madam im adam и не отметил момент так это словосочетание начинается и заканчивается на одинаковые символы (m) =)
...
[Хм... не понял. А к чему был пример? Сокровенный смысл какой?
Недогнал :)]
- чё дуру гнать, нужно было выполнять преобразование симв. к др.
регистру и прочее - как вариант. И еще, не забывай писать модификаторы в конце рега, после слеша - пишешь глобальный поиск
а на деле, его нет. (/g)
Еще вопрос, в какой кодировке у тебя текст, нужна ли локализация?
В довесок, для изучения регов хорошо юзать софтину -
The Regex Coach,The Regulator или RegexBuddy, можно
Комодо Айди (Тоолс -> RxToolkit) и др. Конечно, в опциях
нужно не забыть выставить Perl-совместимость, если использовать
первые три софтины.
Regexp
Недогнал :)]
- чё дуру гнать, нужно было выполнять преобразование симв. к др.
регистру и прочее - как вариант. И еще, не забывай писать модификаторы в конце рега, после слеша - пишешь глобальный поиск
а на деле, его нет. (/g)
Еще вопрос, в какой кодировке у тебя текст, нужна ли локализация?
В довесок, для изучения регов хорошо юзать софтину -
The Regex Coach,The Regulator или RegexBuddy, можно
Комодо Айди (Тоолс -> RxToolkit) и др. Конечно, в опциях
нужно не забыть выставить Perl-совместимость, если использовать
первые три софтины.
Про "глобальный поиск" - так модификатор /L глобально заменяет все символы до конца regexp-a или до конца строки и нет нужды использовать мод. /g
Кодировка - ASCII
"Дуру не гоню" - запустил прилагаемые вами "скрипты" и просто не сообразил, что именно полезного они делают (один из них просто выводит список ASCII символов в hex транскрипции). Моя "задача" - всего-навсего перевести все символы из верхнего регистра в нижний.
...
А русские и украинские символы как переводить будешь?
Кодировки 866, 1252, КОИ8Р, Мас и пр. (в том числе ЮТФ)!!!
Какая у тебя Аскишная таблица?
to cybertom
Кодировки 866, 1252, КОИ8Р, Мас и пр. (в том числе ЮТФ)!!!
Какая у тебя Аскишная таблица?
Ааа... вот оно как :)
Неа, я так еще глубоко не копал (в смысле с разными линг.кодировками)
...
Устанавливаешь нужную локаль в системе,
а затем вызываещь uc или lc в во второй
части рега, в первой искомое выражение
в строке. И все! Никакой мороки!
---
use POSIX qw(locale_h); # Работа с локалью POSIX - позволяет корректно
use locale; # работать с национальными символами
setlocale(LC_CTYPE, "Russian_Russia.866"); # устанавливаем другую локаль
---
options for s///
Если протестируете пример на более длинных (содержащих несколько слов) образцах,
содержащих символы в верхнем регистре, то можно заметить,
что ловеркейсится только первое слово, захватываемое регулярным выражением, а не вся строка.
В приведенном примере обработано будет только первое совпадение, тогда как модификатор /g (s/example/\L$1/g)
заставит обработать все вхождения в строке.
Приведение к нижнему регистру все же решается lc(), а на примеры, приведенные cybertom'ом
я бы рекомендовал обратить внимание и сообразить. В должной мере познавательные примеры.
Вообщем-то пример этот imho иллюстрирует возможности,а не делает что-то конкретное
...
$a = "QWERTYUIOP ASDFGHJKL ZXCVBNM"; print "$a\n";
# посимвольно
$a =~ s/([A-Z])/lc($1)/ge; print "$a\n";
$a =~ s/([a-z])/uc($1)/ge; print "$a\n";
# словами
$a =~ s/([A-Z]+)/lcfirst($1)/ge; print "$a\n";
$a =~ s/([a-z]+)/ucfirst($1)/ge; print "$a\n";
# В целом считаю, что усложнение рег. выражений к
# хорошему не приводит - не так много людей умеющих
# хорошо читать регулярки, да разновидностей движков
# и нотаций регулярок не так мало. Сопровождение софта
# с большим кол-вом регулярки, в том числе спец.техника
# реализующая те или иные фичи - дело дорогостоящее!
# Поэтому, было бы разумно находить компромисс решений
# по использованию тех или иных особенностей, останавливая
# свой выбор прежде на читаемости кода, конечно не забывая
# и о производительности - надо делать профайлинг!
# Конечно в свете этого, вызов функций далеко не оптимален
# в плане скорости, но в сущности почему бы и нет!
Можно так, как вариант
$text=~tr/A-ZА-Я/a-zа-я/;
...
Слишком просто, наверное будет,
ненадежно и зависит от локали
набранной программы, лучше тогда
указать шестнадцатеричный диапазон,
или символов (баш на баш), но не так,
одназначно, в самой регулярке должен
быть внутренний механизм, надо бы его надыбать!
теги
:)
print "Ура, у меня получилось!" ;)Как выделить рамкой?
Слишком просто
ненадежно и зависит от локали
набранной программы, лучше тогда
указать шестнадцатеричный диапазон,
или символов (баш на баш), но не так,
одназначно!
за лет 5 этот "слишком простой" код не подвел еще ни разу
...
Тогда, я согласен с использованием \l \L ... \E и пр. модиф.
чем с таким вариантом. Во первых громозко, ну может и читаемо,
ну в чем смысл тогда? Конструкции модификаторы наверное эффективнее!
А во вторых, я против употребления нац. символов в регулярке,
лучше использовать шестн. диапазоны символов при трансляции! Не
намного сложнее, но без проблем. Кстати, как представить русскояз.
символы в кодировке UTF8 и UNICODE? ;))
Очень будет оригинально! Видел ли кто локализацию русских строк
в QT Designer ? Очень забавно! Забей русское меню и посмотри код!
...
Усе!
...
Почему ненадежно выражение $text=~tr/A-ZА-Я/a-zа-я/;
верно оно для кодировок ср1251 и ISO8859-5
неверно для кодировок ср866 и KOI8-r (RFC1489)
должно быть:
KOI8-r: tr/Ю-Ъ/ю-ъ/;
cp866: tr/А-ПР-Я/а-пр-я/;
При применении диапазонов символов обязательно надо
удостовериться c соответствующей используемой таблицой
расширенного диапазона ASCII на правильность диапазона!
Теперь всё!
Фантастика! - Я
Фантастика!
- Я всегда думал что проще все перегонять в одну кодировку и только с ней работать, а оказывается не всегда :)
...
Конечно под Рутом в 1251 очень конфортно!
Спору нет!
Некоторое время назад у меня была потребность преобразовать
кодировку ср866 в Юникод. И что? Ни одна из программ корректно
это не делала! Факт! Символы псевдографики и другие символы
отображались не корректно! Пришлось написать простую программу
которая производила конверсию правильно. Таким образом, чтобы
глифы ср866 были правильными глифами Юникода. Т.е. простая
табличка соответствий однобайтной кодировки соответствующими
символами Юникода. (ситуация была - лет пять назад)
Из этого вопрос - Как корректно выполнить конверсию однобайтных
кодировок (их много, естественно) в Юникод (или UTF8) внутренними
силами Perl (базовыми модулями).
Правильно - из
Правильно - из любой полноценно поддерживаемой кодировки встроенными средствами Перл прямо кодировать в unicode. Например полноценно поддерживаемой считается koi8-r, соответственно, все другие кодировки просто таблично перекодировать в koi-8r.
Искать unicode в man perl.
Если не все перекодируется как следует - в зависимости от наличия свободного времени:
1. написать патч и официально его оформить,
2. отправить на perl.org баг,
3. спросить на форуме perl и перекодировать руками.
...
Вот спасибо!
Но все же как конвертировать в UNICODE?
Простой пример, представления у меня есть,
хотелось увидеть решение других, свое обязательно представлю!