与 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); ?>
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
mb_ereg_replace — 使用多字节支持替换正则表达式
扫描 string
中与 pattern
匹配的内容,然后用 replacement
替换匹配的文本。
pattern
正则表达式模式。
可以在 pattern
中使用多字节字符。
replacement
替换文本。
string
要检查的 字符串。
options
版本 | 说明 |
---|---|
8.0.0 |
options 现在可以为空。 |
7.1.0 | 该函数检查 string 是否对当前编码有效。 |
7.1.0 | e 修饰符已弃用。 |
注意:
内部编码或 mb_regex_encoding() 指定的字符编码将用作此函数的字符编码。
在处理不受信任的输入时,切勿使用 e
修饰符。不会发生自动转义(如 preg_replace() 中已知的那样)。如果不注意这一点,很可能在您的应用程序中创建远程代码执行漏洞。
与 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); ?>
我在尝试为字典项目解析数据库中的表格行(所有内容都设置为 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 会导致我的数据库中一半的字符丢失。
我发布此解决方案是为了以防万一有人遇到类似的问题。希望这在您需要类似内容时对您有所帮助。
<?php
$pattern = "([あ-ん]+)[0-9]+";
$string = mb_ereg_replace($pattern, '「\\1」:\\0', $string);
?>
您可以在替换中使用 \\n 来捕获组。
如果 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);
?>
一个简单的 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 的改进]
在替换字符串中引用捕获的符号
<?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>..)" 这样的命名子模式一起使用,因为当存在命名子模式时,非命名子模式无法被捕获。
从 PHP 5.4 开始,为了将字符转换为大写或小写,或者重写一些 URI,而无需关心初始编码,转写会更容易(可能是最好的方法):参见 https://php.net/manual/fr/transliterator.transliterate.php 和 http://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 »
通过 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;
}
您是否在寻找用于多字节字符串的 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('<', '>', '"', ''');
for ($i=0; $i<sizeof($pattern); $i++) {
$str = mb_ereg_replace($pattern[$i], $replacement[$i], $str);
}
return $str;
}
?>
关于 mb_str_ireplace() 函数:我将它与 mb_eregi_replace() 进行了基准测试,用于单字符替换,结果发现它明显更慢。尽管避免了 ereg 调用,但我认为对于这种情况而言,while 循环最终会拖慢速度。
如果您想替换像 "ä" 或 "ø" 这样的字符,可以使用 mb_ereg_replace,但它非常慢。str_replace 速度快得多,而且也可以处理像 "ä" 或 "ø" 这样的字符!
我认为这与 str_replace 在字节级别工作,并且不关心字符有关。
希望这对您有所帮助。
通过 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
正如 trng 之前提到的,您可以使用 \\n 进行替换,但不要使用 preg_replace 文档中提到的 \\\\n。因此,字符串定义应类似于
$str = '\\1';