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 现在可以为空。
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
6 年前
如果 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);
?>
匿名
17 年前
“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 jam, \\2 juice, \\3 squash', 'apple orange lemon').'<br>'; // apple jam, orange juice, lemon squash

// (2) \k<number> 符号: (也大于 9) (也可以写成 \k'number')
echo mb_ereg_replace('(\S*) (\S*) (\S*)', '\k<1> jam, \k<2> juice, \k<3> squash', 'apple orange lemon').'<br>'; // (与上面相同)

// (3) \k<word> 符号: (也可以写成 \k'word')
echo mb_ereg_replace('(?<word1>\S*) (?<word2>\S*) (?<word3>\S*)', '\k<word1> jam, \k<word2> juice, \k<word3> squash', 'apple orange lemon').'<br>'; // (与上面相同)

// 注意,像 "(\S*)" 这样的非命名子模式不应该与像 "(?<word>..)" 这样的命名子模式一起使用,因为当存在命名子模式时,非命名子模式无法被捕获。
j-fr dot fortier at wanadoo dot fr
5 年前
从 PHP 5.4 开始,为了将字符转换为大写或小写,或者重写一些 URI,而无需关心初始编码,转写会更容易(可能是最好的方法):参见 https://php.net/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');
// 罗马数字也是如此
$str = mb_eregi_replace('\bM{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b', "strtoupper('\\0')", $str, 'e');
return $str;
}
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');
// 罗马数字也是如此
$str = mb_eregi_replace('\bM{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})\b', "strtoupper('\\0')", $str, 'e');
return $str;
}

Marco Marsala 博士
Network Solution srl
http://www.realizzazionesitigenova.it
squeegee
17 年前
嗯,如果您只计算一次查找和替换字符串的长度,而不是在每次循环中都计算,那么它可能会快很多。
ms2705335 at gmail dot com
7 年前
正如 trng 之前提到的,您可以使用 \\n 进行替换,但不要使用 preg_replace 文档中提到的 \\\\n。因此,字符串定义应类似于
$str = '\\1';
To Top