Archive for the ‘regexp’ Category

Переносы строки и Json

Monday, January 28th, 2008

Столкнулся с такой проблемой, есть текст с переносом строки внутри

Привет
Как дела?

Когда пытаюсь передать её через Ajax под видом JSON получается следующее

{custom:"Привет
Как дела?"}

Работающий перенос строки останавливает работу скрипта. Надо было убрать перенос для js, но что бы он одновременно работал в форме куда этот текст и вставлялся

$value = preg_replace('#[\n\r]+#', "\\n", $value);

Теперь все стало работать так как текст выглядит так

{custom:"Привет\nКак дела?"}

Исправляем старый php с помощью perl

Friday, January 4th, 2008

Как известно, а если нет то огорчит, шестая версия php больше не будет поддерживать такой синтаксис как <? или <?=. И если в пятерке этот можно было поправить в php.ini файле и разрешить работу старых объявлений, теперь это будет не возможно. Что же делать? Горевать? Нет, использовать этот небольной код

find * -type f -exec perl -i -wpe 's/<\?[^(=|php)]/<\?php /g;
s/<\?=/<\?php echo /g;' {} \;

Итак, чем он занимается.

find * -type f - находим все файлы
-exec perl -i -wpе - натравливаем на них perl с его регуляркой
s/<\?[^(=|php)]/<\?php /g; - первая проверка, найти все s/<\?=/<\?php echo /g;’ - вторая проверка ловит старые коды <?= и меняет их на <\?php echo

в результате код

<?
	phpinfo();
?>
<?=$e?>
<?php $e++; ?>

выглядит так

<?php
	phpinfo();
?>
<?php echo $e?>
<?php $e++; ?>

PS: Вставляя в командную строку не забудьте соединить обе строки.
PS2: И сделать бакап ;)

Функции в регулярке

Wednesday, December 5th, 2007

Как работает preg_replace понятно, нашел совпадения, заменил. А что если надо не просто заменить а предварительно обратобать соединение а уж потом его заменить. Если речь идет об одной строчке то все более менее ясно, но если совпадений много и все их надо обработать.
Вот небольшой отрывок error.log.

[Wed Oct 10 16:32:04 2007] [error] [client 212.65.64.18] ...

Теперь предположим надо получить более понятную дату. Таких строчек в файле мого 50 либо придется писать большой код либо, надо одти на хитрость. использовать функцию внутри preg_replace

function sp($logtime){
//ваш код
return $logtime;
}
$text = preg_replace('/^\[(.*?)\]/im',
    " '\['.sp('\\1').']' "
    , $text);

Теперь кусок совпавшего регулярным выражениям кода отправляется в нашу функцию и результат ее обработки вставляется обратно. Особо обратите внимание на кавычки, это важно, иначе работать не будет.

Количество совпадений

Thursday, November 8th, 2007

У wikipedia есть лозунг - “все есть статья”. Чем больше работаешь с perl, тем больше понимаешь, что неофициальный лозунг языка может звучать “все есть регулярное выражение”. Вот пример как подсчитать количество найденных вхождений в выражение. Скажем сколько букв “о” в традиционном “hello world”

#!/usr/bin/perl

$text = 'hello world';
$text =~ s/[^o]//igs;
print length($text)."\n";
# 2

Зацените красоту кода.

Проверка с присвоением

Tuesday, October 9th, 2007

Как то прочел, что знаменитый Ларри Уолл (Larry Wall), создатель perl всегда отдавал предпочтение функциям которые хоть и не выглядели читабельными но были короткими. Странно, учитывая то, что он был лингвистом и должен был любить красоту слова. Тем не менее, лаконичность языка perl достаточно известна. Вот небольшой пример регулярных выражений где можно подсократить.

#!/usr/bin/perl

$a= 'Larry Wall';

if($a =~ m/(larry)\s(.*)/i){
	print $2;
}
# Wall

Регулярное выражение не только проверяет наличие в тексте слова ‘larry’, но и присваивает совпадения переменным $1 и $2

pattern

Wednesday, October 3rd, 2007

Еще одна надежда избавиться от кусков JS кода в будущем, это атрибут pattrn. С помошью регулярных выражений, он проверяет ввел ли пользователь данные соответствующие маске.

<input required="true" pattern=".*@.*\..*" type="text"
value="" name="email_address" />

вот как выглядит
pattern
по прежнему нет возможности изменить тип предупреждения, а значит очень популярным это не будет

.* - любой текст
@ - собачка
.* - любой текст
\. - точка
.* - любой текст

другой вопрос на каком уровне будут поддерживаться регулярные выражения, судя по тому, что инфы про это я нигде не нашел, боюсь нас ждет еще один стандарт регулярки

Исправляем id на xml:id в DOMDocument

Thursday, August 16th, 2007

Недавно писал про, даже не знаю как назвать баг или фичу или что то еще, странность getElementById() для DOMDocument и вот небольшое решение этого.
Создаю класс на основе DOMDocument

class DomDoc extends DOMDocument{

	function loadXML($link){
		$link=preg_replace("/ id=/i", " xml:id=", $link);
		parent::loadXML($link);
	}

}

Как наверно наглядно, весь текст, пока он еще текст, проворачиваю на наличие id и заменить на xml:id а после уже вызываю родительский метод загрузки. после этого уже сам непосредственный код

$link = '<h1 id="link">mymans.org</h1>';

$doc = new DomDoc();
$doc->loadXML($link);
echo "The element is: " . $doc->getElementById('link')->tagName ;

как результат получу

The element is: h1

Данные в форму

Wednesday, June 6th, 2007

Рассмотрим простой пример у нас есть форма с select на странице и мы хотим что бы каждый раз происходил выбор страница перезагружалась и в select было выбранное то что было на предыдущей странице.

<select name="page">
<?php
while($a<10){
echo "<option value=\"$a\">$a<option>";
}
?>
</select>

При передачи url будет выгладить так url.html?page=5

теперь при формировании select надо будет поставить selected="selected" там где $a==5. Сделать это можно через if а можно воспользоваться регуляркой

<select name="page">
<?php
while($a<10){
$a1=preg_replace("/^($_GET[page])$/i", "\$1\" selected=\"selected", $a);
echo "<option value=\"$a1\">$a<option>";
}
?>
</select>

вот и все! Не нужно никаких проверок или чего нибудь еще. Что деделает формула
$a1 это последовательность чисел от 0 до 9
preg_replace("/^($_GET[page])$/i”, “\$1\” selected=\”selected”, $a) - здесь мы говорим найди в число 5 и замени его на 5" selected="selected, обратите внимание на кавычки.
И далее мы помещаем наше $а внутрь echo

<option value="5" selected="selected">5<option>

Кроме того очень важно что бы в регулярном выражении стояли ^ и $ потому что если $_GET[page] не будет определен или будет равен скажем 20 то вы будете уверены что формула не сработает.

Статические URL

Monday, May 28th, 2007

Большие сайты любят передавать переменные в адресной стоке не явно, например вместо того что бы в адресной строке стояло
wiki.php?param1=edit&param2=132 хочется видеть wiki/edit/123/ для этого нам понадобится использовать МodRewrite в .htaccess. пишем там следующее

<IfModule mod_rewrite.c>
RewriteBase /
RewriteEngine On
RewriteRule ^wiki/([^/]+)/([^/]+)/?$
    /wiki/index.php?param1=$1&param2=$2 [L]
</IfModule>

попробуем расшифровать регулярку
^wiki/ - если в начале адреса стоит слово wiki и затем слеш (/)
(([^/]+)) - далее любое количество букв, или хотя бы один и символов кроме слеша, берем в скобки что бы использовать как $1
далее такая же вторая группа будет идти как $2
/? - один или вообще отсутствие слеша

Урезанные книжки

Thursday, May 17th, 2007

На сайте у машкова книжки можно скачать в разном формате, но нужная мне книга ни как не хотела становится в нужный формат, что бы с легко ее распечатать, строка с права усечена и перенесена на следующую строку. Что же делать? И вот я стал рассуждать, если принять во внимание что орфография книги верна, то можно найти все строки которые нужно превратить в одну.

Любая строка, заканчивающаяся не на точку вопросительный или восклицательный знак и двоеточие, должна быть соединенна с ниже следующей, поэтому код такой

/[^.:!?]$/

дальнейший код написать было не так уж сложно.