I got a pretty nasty error while trying to parse table rows(all contents were set to UTF-8) from the database for a dictionary project. The idea was to get all the rows from the first table (that is a table with bulgarian phrase in the first field, and its translation in english, french and german in the next fields). I needed to index all the bulgarian words that are found in the table to make an intelligent search. And that is where my headache started.
First of all, even with mb_strtolower() a lot of cyrillic characters went corrupted (ex: 'т,ъ,у,ф,б,г,з,ж,' etc...). After an hour of different attempts I got such a solution:
<?php
mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");
$rows = $db->getRows();
$contents = array();
foreach ($rows as $eachRow)
{
$cleared = str_replace($commonWords, ' ', mb_strtolower(stripslashes($eachRow['bulgarian']), 'UTF-8' ));
if (trim($cleared) != '') $contents[] = trim($cleared);
}
$list = array();
foreach ($contents as $eachRow)
{
$exploded = explode(' ', $eachRow);
foreach ($exploded as $eachExpl)
{
$eachExpl = mb_ereg_replace('[^а-я ]',' ', $eachExpl);
if (trim($eachExpl) != '')
if (!in_array($eachExpl, $list, true)) $list[] = trim($eachExpl);
}
}
?>
To work properly I got to set all the internal encoding settings to UTF-8. Else the default Latin-1 got half my database with missing characters.
I am posting this solution just in case someone has encountered a similar problem. Hope it helps you in case you need something like that.
mb_ereg_replace
(PHP 4 >= 4.2.0, PHP 5)
mb_ereg_replace — マルチバイト文字列に正規表現による置換を行う
説明
string mb_ereg_replace
( string $pattern
, string $replacement
, string $string
[, string $option = "msr"
] )
string から pattern にマッチする文字列を探し、 見つかった文字列を replacement で置換します。
パラメータ
- pattern
-
正規表現パターン。
マルチバイト文字を pattern で使用することができます。
- replacement
-
置換文字列。
- string
-
調べたい文字列。
- option
- option パラメータで、マッチングの動作を変更可能です。 i を指定した場合、大文字・小文字が 区別されなくなります。 x を指定した場合、空白が無視されます。 m を指定した場合、マルチラインモードとなり、 改行文字も "." に含まれるようになります。 p を指定した場合、POSIX モードとなり、 改行も通常文字とみなされるようになります。 e を指定した場合、文字列 replacement がPHPの式として評価されます。
返り値
成功した場合に結果の文字列、エラー時に FALSE を返します。
注意
注意: 内部エンコーディングあるいは mb_regex_encoding() で指定した文字エンコーディングを、 この関数の文字エンコーディングとして使用します。
警告
信頼できない入力に対しては、 絶対に e 修正子を使用してはいけません。 (preg_replace() と同様、) 自動的なエスケープは行いません。 このことを忘れていると、自分の書いたアプリケーションにリモートコード実行の脆弱性を作りこんでしまうことになります。
参考
- mb_regex_encoding() - 現在の正規表現用のエンコーディングを文字列として返す
- mb_eregi_replace() - マルチバイト文字列に大文字小文字を区別せずに正規表現による置換を行う
mb_ereg_replace
daemoneye at gmail dot com
03-Feb-2009 11:53
03-Feb-2009 11:53
keizo at gomo dot jp
24-Jul-2008 06:32
24-Jul-2008 06:32
<?php
$pattern = "([あ-ん]+)[0-9]+";
$string = mb_ereg_replace($pattern, '「\\1」:\\0', $string);
?>
you can use \\n for capture group in replacement
gmx dot net at ulrich dot mierendorff
01-Jul-2008 04:39
01-Jul-2008 04:39
If you want to replace characters like "ä" or "ø" you can use mb_ereg_replace, but it is very slow. str_replace is much faster and also works with characters like "ä" or "ø"!
I think this has something to with the fact that str_replace works on byte level and does not care about characters.
I hope that can help.
04-Dec-2006 05:36
'i' option does not work correctly with multibyte characters. The function does not locate/replace the multibyte string if it's different case then specified on multibyte needle which is in different case.
squeegee
01-Nov-2006 04:41
01-Nov-2006 04:41
well, if you just calculated the length of the find and replace strings once instead of on every loop, it would likely speed it up a lot.
mpnicholas [@t] gmail (dot) com
10-Jul-2006 12:09
10-Jul-2006 12:09
Regarding the mb_str_ireplace() function: I benchmarked it against mb_eregi_replace() for single-character substitution, and it was significantly slower. Despite avoiding the ereg call, I think the while loop ends slowing you down too much for this to be practical.
vondrej(at)gmail(dot)com
27-Feb-2006 12:47
27-Feb-2006 12:47
Are you looking for htmlentities() for multibyte strings? This might help you - it just replace <, >, ", '
<?php
/**
* Multibyte equivalent for htmlentities() [lite version :)]
*
* @param string $str
* @param string $encoding
* @return string
**/
function mb_htmlentities($str, $encoding = 'utf-8') {
mb_regex_encoding($encoding);
$pattern = array('<', '>', '"', '\'');
$replacement = array('<', '>', '"', ''');
for ($i=0; $i<sizeof($pattern); $i++) {
$str = mb_ereg_replace($pattern[$i], $replacement[$i], $str);
}
return $str;
}
?>
faxe at neostrada dot pl
10-Aug-2005 12:52
10-Aug-2005 12:52
A simple mb_str_ireplace() implementation - a faster (?) replacement for non-regexp multi-byte string replacement:
<?php
function mb_str_ireplace($co, $naCo, $wCzym)
{
$wCzymM = mb_strtolower($wCzym);
$coM = mb_strtolower($co);
$offset = 0;
while(!is_bool($poz = mb_strpos($wCzymM, $coM, $offset)))
{
$offset = $poz + mb_strlen($naCo);
$wCzym = mb_substr($wCzym, 0, $poz). $naCo .mb_substr($wCzym, $poz+mb_strlen($co));
$wCzymM = mb_strtolower($wCzym);
}
return $wCzym;
}
?>
[thiago - EDITOR NOTE: This function has improvements from d-okumura [aat] fi{dot}kyd[dot]co.jp]
