Регулярные выражения для обработки строк UTF-8 в PHP, плагин simple-syn для WordPress

В языке программирования PHP строковые функции (например, strlen, substr, preg_replace_callback, preg_match и другие) при использовании регулярных выражений выдают некорректные результаты, если в строке имеются символы национального алфавита в кодировке utf-8. Подробнее смотрим тут: http://www.phpwact.org/php/i18n/utf-8 (Английский!). Обещают в php6 исправить.
Столкнулась при установке плагина symple-syn для WordPress (синонимайзер), для замены слов синонимами. Нужно было именно для русского текста в кодировке utf-8.
Замена строки 25 в плагине symple-syn для WP

$content=preg_replace_callback('#([a-zA-Z]+)#is','repl',$content);

на

$content=preg_replace_callback('#([а-яА-Я]+)#is','repl',$content);

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

В итоге делаем так:
Для начала сохраняем файл плагина в кодировке utf-8.
Заменяем функцию simplesyn, строка 24

function simplesyn($content){
	$content=preg_replace_callback('#([a-zA-Z]+)#is','repl',$content);
	return $content;
}

на:

function simplesyn($content){
    $content = iconv('UTF-8','cp1251', $content);
    $cp12_pat = iconv("UTF-8", "CP1251", "а-яА-Я");
/*++patch русский utf8*/	$content=preg_replace_callback('#(['.$cp12_pat.']+)#is','repl',$content);
/*--patch русский utf8**///	$content=preg_replace_callback('#([a-zA-Z]+)#is','repl',$content);
    $content = iconv('cp1251','UTF-8', $content);
    return $content;
}

, а функцию repl

function repl($matches){
	global $wpdb;
  	$table_name = $wpdb->prefix . "simplesyn";
  	$word=$matches[1];
	$row=$wpdb->get_row("SELECT * FROM `$table_name` WHERE `word`='$word'", ARRAY_A, 0);
  	if ($row['word']!=""){
  		$spl=explode(',',$row['syns']);
		if ((ord(substr($word,0,1)>64))&&(ord(substr($word,0,1)<91)))
		 return ucwords($spl[array_rand($spl)]);
		else return $spl[array_rand($spl)];
	}
	else return $word;
}

на

function repl($matches){
	global $wpdb;
  	$table_name = $wpdb->prefix . "simplesyn";
  	$word=$matches[1];
        $word_utf8 = iconv('cp1251', 'UTF-8',$word);
	$row=$wpdb->get_row("SELECT * FROM `$table_name` WHERE `word`='$word_utf8'", ARRAY_A, 0);
  	if ($row['word']!=""){
  		$spl=explode(',',$row['syns']);
                $res = $spl[array_rand($spl)];
                $res = iconv('UTF-8', 'cp1251', $res);
                $chr1 = ord(substr($word,0,1));
		if (($chr1>191)&&($chr1<224))
		 return ucwords($res);
		else return $res;
	}
	else return $word;
        
}

Сохраняем, проверяем. Все должно работать. На выходе получаем синонимизацию.

Если кому нужен готовый модуль, пишите, вышлю.

Рекомендовать в Социальных сетях:
 

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *