PHP Conference Japan 2024

mb_ereg_replace

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

mb_ereg_replace支援多位元組的正規表示式取代

說明

mb_ereg_replace(
    字串 $pattern,
    字串 $replacement,
    字串 $string,
    ?字串 $options = null
): 字串|false|null

string 中搜尋符合 pattern 的部分,然後將符合的文字取代為 replacement

參數

pattern

正規表示式模式。

多位元組字元可以用在 pattern 中。

replacement(取代字串)

取代的文字。

string(字串)

要檢查的 字串

options(選項)
搜尋選項。 詳見 mb_regex_set_options() 的說明。

返回值

成功時返回結果 字串,錯誤時返回 false。如果 string 對於目前的編碼無效,則返回 null

更新日誌

版本 說明
8.0.0 options 現在可以為 null。
7.1.0 此函式會檢查 string 是否對目前的編碼有效。
7.1.0 e 修飾符已被棄用。

注意事項

注意:

此函式將使用內部編碼或 mb_regex_encoding() 指定的字元編碼作為字元編碼。

警告

處理不受信任的輸入時,切勿使用 e 修飾符。不會進行自動跳脫字元(如同 preg_replace() 中的行為)。不注意這一點很可能會在您的應用程式中造成遠端程式碼執行漏洞。

參見

新增筆記

使用者貢獻的筆記 17 則筆記

Pluche
13 年前
與 preg_replace 不同,mb_ereg_replace 不使用分隔符號

preg_replace 的範例
<?php $data = preg_replace("/[^A-Za-z0-9\.\-]/","",$data); ?>

mb_ereg_replace 的範例
<?php $data = mb_ereg_replace("[^A-Za-z0-9\.\-]","",$data); ?>
daemoneye at gmail dot com
15 年前
我在嘗試從資料庫中解析表格列(所有內容都設定為 UTF-8)以進行字典專案時,遇到了一個相當棘手的錯誤。我的想法是從第一個表格(第一個欄位是保加利亞語片語,後續欄位是其英文、法文和德文翻譯的表格)中取得所有列。我需要索引表格中找到的所有保加利亞語單詞,以進行智慧搜尋。這就是我頭痛的開始。

首先,即使使用 mb_strtolower(),許多西里爾字母也會損毀(例如:「т,ъ,у,ф,б,г,з,ж」等)。經過一個小時的不同嘗試後,我得到了這樣的解決方案

<?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);
}
}

?>

為了正確運作,我必須將所有內部編碼設定設為 UTF-8。否則預設的 Latin-1 會導致我的資料庫一半的字元遺失。

我發布這個解決方案,以防有人遇到類似的問題。希望它能在您需要類似功能時幫助您。
trng
13 年前
您可以在取代中使用 \\n 作為捕獲群組。
而且您不能使用 $n 符號(與 preg_replace 函式不同)。
匿名
8 年前
Pluche 的評論真的應該添加到文檔中,最好放在「$pattern」參數描述下。這對於使用此函式至關重要。
keizo at gomo dot jp
16 年前
<?php
$pattern
= "([あ-ん]+)[0-9]+";
$string = mb_ereg_replace($pattern, '「\\1」:\\0', $string);
?>

您可以在取代中使用 \\n 作為捕獲群組
Alexey Khrulev
7 年前
如果 PHP 腳本的編碼與要由 mb_ereg_replace() 處理的字串的編碼不同,則不能只在腳本中編寫模式。 $pattern 和 $replacement 都必須轉換為與要處理的字串相同的編碼。在此範例中,腳本採用 UTF-8 編碼,要處理的檔案採用 UTF-16LE 編碼

<?php
$file_encoding
= 'UTF-16LE';
mb_regex_encoding( $file_encoding );

$pattern = "aaa";
$replacement = "AAA";
$pattern_encoded = mb_convert_encoding( $pattern, $file_encoding, 'UTF-8' );
$replacement_encoded = mb_convert_encoding( $replacement, $file_encoding, 'UTF-8' );

$result = mb_ereg_replace( $pattern_encoded, $replacement_encoded, file_get_contents('UTF-16LE.txt') );
file_put_contents('UTF-16LE-updated.txt', $result);
?>
匿名使用者
18 年前
「i」選項在多位元組字元的情況下無法正常運作。如果多位元組字串的大小寫與指定的多位元組搜尋字串的大小寫不同,該函式將無法找到/取代該多位元組字串。
faxe at neostrada dot pl
19 年前
一個簡單的 mb_str_ireplace() 實作 - 一個更快(?)的非正規表達式多位元組字串取代方法

<?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 - 編輯註記:此函式包含了來自 d-okumura [aat] fi{dot}kyd[dot]co.jp 的改進]
匿名使用者
2 年前
在取代字串中引用捕獲的標記法

<?php

// (1) \\number 表示法:(1 到 9,不可大於 9)
echo mb_ereg_replace('(\S*) (\S*) (\S*)', '\\1 果醬, \\2 果汁, \\3 汁', '蘋果 柳橙 檸檬').'<br>'; // 蘋果 果醬, 柳橙 果汁, 檸檬 汁

// (2) \k<number> 表示法:(也可大於 9) (也可寫成 \k'number')
echo mb_ereg_replace('(\S*) (\S*) (\S*)', '\k<1> 果醬, \k<2> 果汁, \k<3> 汁', '蘋果 柳橙 檸檬').'<br>'; // (同上)

// (3) \k<word> 表示法:(也可寫成 \k'word')
echo mb_ereg_replace('(?<word1>\S*) (?<word2>\S*) (?<word3>\S*)', '\k<word1> 果醬, \k<word2> 果汁, \k<word3> 汁', '蘋果 柳橙 檸檬').'<br>'; // (同上)

// 注意:像 "(\S*)" 這樣的非命名子模式不應與像 "(?<word>..)" 這樣的命名子模式一起使用,因為當存在命名子模式時,非命名子模式將無法被捕獲。
j-fr dot fortier at wanadoo dot fr
5 年前
自 PHP 5.4 起,若要將字元轉換為大寫或小寫,或重寫某些 URI,而不需考慮初始編碼,音譯會更容易(而且可能是最好的方法):請參閱 https://php.dev.org.tw/manual/fr/transliterator.transliterate.phphttp://userguide.icu-project.org/transforms/general

例如(使用 create 方法)(法文:將所有帶有重音符號的字元 -éèàîïùç...- 替換為 ASCII 字元)
<?php
$transliterator
= Transliterator::create("NFD; [:Nonspacing Mark:] Remove; NFC;");
echo
$transliterator->transliterate("Héhé, ça marche !");
?>
// 結果:« Hehe, ca marche ! »

將片語重寫為 URI(使用 createFromRules 方法)
<?php
$transliterator
= Transliterator::createFromRules("::Latin-ASCII; ::Lower; [^[:L:][:N:]]+ > '-';");
echo
trim($transliterator->transliterate("Héhé, ça marche !"), '-');
?>
// 結果:« hehe-ca-marche »
marco at thenetworksolution dot it
10 年前
使用 mb_eregi_replace 選擇性地將字串的某些部分轉換為大寫

$str = mb_eregi_replace('\b([0-9]{1,4}[a-z]{1,2})\b', "strtoupper
('\\1')", $str, 'e');

完整的範例,說明如何修正手動輸入的地址,將每個單字的首字母大寫,並保留大寫的羅馬數字和門牌號碼後面的字母 A、B、C)

function ucAddress($str) {
// 首先將所有字母轉換為小寫,然後使用預設的 ucwords 函式
$str = ucwords(strtolower($str));
// 接著修正預設 ucwords 的結果...
// 將門牌號碼後面的字母轉換為大寫(上面使用 strtolower 轉換為小寫)
$str = mb_eregi_replace('\b([0-9]{1,4}[a-z]{1,2})\b', "strtoupper
('\\1')", $str, 'e');
// 羅馬數字也一樣
```php
```php
}
vondrej(at)gmail(dot)com
18 年前
您是否正在尋找多位元組字串的 htmlentities() 函式?這可能對您有所幫助 - 它只會取代 <、>、"、'

<?php
/**
* htmlentities() 的多位元組版本 [精簡版 :)]
*
* @param string $str
* @param string $encoding
* @return string
**/
function mb_htmlentities($str, $encoding = 'utf-8') {
mb_regex_encoding($encoding);
$pattern = array('<', '>', '"', '\'');
$replacement = array('&lt;', '&gt;', '&quot;', '&#39;');
for (
$i=0; $i<sizeof($pattern); $i++) {
$str = mb_ereg_replace($pattern[$i], $replacement[$i], $str);
}
return
$str;
}
?>
mpnicholas [@t] gmail (dot) com
18 年前
關於 mb_str_ireplace() 函式:我將其與 mb_eregi_replace() 進行了單字元替換的基準測試,發現它明顯較慢。儘管避免了 ereg 呼叫,但我認為 while 迴圈最終會讓速度變慢,以至於不切實際。
gmx dot net at ulrich dot mierendorff
16 年前
如果您想替換像「ä」或「ø」這樣的字元,您可以使用 mb_ereg_replace,但它非常慢。 str_replace 快得多,而且也適用於像「ä」或「ø」這樣的字元!

我認為這與 str_replace 在位元組層級運作並且不關心字元的事實有關。
希望這能有所幫助。
marco at thenetworksolution dot it
10 年前
使用 mb_eregi_replace 選擇性地將字串的某些部分轉換為大寫

$str = mb_eregi_replace('\b([0-9]{1,4}[a-z]{1,2})\b', "strtoupper
('\\1')", $str, 'e');

完整的範例,說明如何修正手動輸入的地址,將每個單字的首字母大寫,並保留大寫的羅馬數字和門牌號碼後面的字母 A、B、C)

function ucAddress($str) {
// 首先將所有字母轉換為小寫,然後使用預設的 ucwords 函式
$str = ucwords(strtolower($str));
// 接著修正預設 ucwords 的結果...
// 將門牌號碼後面的字母轉換為大寫(上面使用 strtolower 轉換為小寫)
$str = mb_eregi_replace('\b([0-9]{1,4}[a-z]{1,2})\b', "strtoupper
('\\1')", $str, 'e');
// 羅馬數字也一樣
```php
```php
}

Marco Marsala 博士
Network Solution srl
http://www.realizzazionesitigenova.it
squeegee
18 年前
嗯,如果您只計算一次查找和替換字串的長度,而不是在每次迴圈中都計算,那麼它可能會大大加快速度。
ms2705335 at gmail dot com
7 年前
正如 trng 之前提到的,您可以使用 \\n 進行替換,但不能像 preg_replace 文件中提到的那樣使用 \\\\n。 因此,字串定義將如下所示
```php
To Top