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 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
18 年前
好吧,如果你只计算一次查找和替换字符串的长度,而不是在每个循环中都计算,它可能会大大加快速度。
ms2705335 at gmail dot com
7 年前
正如 trng 之前提到的,你可以使用 \\n 进行替换,但不要像 preg_replace 文档中提到的那样使用 \\\\n。因此字符串定义将类似于
$str = '\\1';
To Top