与 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 现在可以为 null。 |
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';