指向 Oniguruma 正则表达式语法的旧链接不再有效,有一个有效的链接
https://github.com/geoffgarside/oniguruma/blob/master/Syntax.txt
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
mb_ereg — 支持多字节的正则表达式匹配
pattern
搜索模式。
string
搜索的 string。
matches
如果在 pattern
的圆括号子字符串中找到匹配项,并且函数在调用时传递了第三个参数 matches
,则匹配项将存储在数组 matches
的元素中。如果未找到匹配项,则 matches
将被设置为一个空数组。
$matches[1] 将包含从第一个左括号开始的子字符串;$matches[2] 将包含从第二个左括号开始的子字符串,依此类推。 $matches[0] 将包含匹配的完整字符串的副本。
返回 pattern
是否与 string
匹配。
版本 | 描述 |
---|---|
8.0.0 | 此函数现在在成功时返回 true 。以前,如果在 string 中找到与 pattern 的匹配项,并且传递了 matches ,则它返回匹配字符串的字节长度。如果可选参数 matches 未传递或匹配字符串的长度为 0 ,则此函数返回 1 。 |
7.1.0 |
mb_ereg() 现在将 matches 设置为一个空的 array,如果没有任何匹配。以前,在这种情况下 matches 不会被修改。 |
注意:
内部编码或由 mb_regex_encoding() 指定的字符编码将用作此函数的字符编码。
指向 Oniguruma 正则表达式语法的旧链接不再有效,有一个有效的链接
https://github.com/geoffgarside/oniguruma/blob/master/Syntax.txt
请注意,mb_ereg() 不支持 \uFFFF Unicode 语法,而是使用 \x{FFFF}。
<?PHP
$text = 'Peter is a boy.'; // 英语
$text = 'بيتر هو صبي.'; // 阿拉伯语
//$text = 'פיטר הוא ילד.'; // 希伯来语
mb_regex_encoding('UTF-8');
if(mb_ereg('[\x{0600}-\x{06FF}]', $text)) // 阿拉伯语范围
//if(mb_ereg('[\x{0590}-\x{05FF}]', $text)) // 希伯来语范围
{
echo "文本包含一些阿拉伯语/希伯来语字符.";
}
else
{
echo "文本不包含阿拉伯语/希伯来语字符.";
}
?>
preg_match() 和 mb_ereg() 之间的区别之一
关于“捕获的圆括号子模式”。
<?php
preg_match('/(abc)(.*)/', 'abc', $match);
var_dump($match);
mb_ereg('(abc)(.*)', 'abc', $match);
var_dump($match);
?>
array(3) {
[0]=>
string(3) "abc"
[1]=>
string(3) "abc"
[2]=>
string(0) "" // <-- "string"(0) "" : preg_match()
}
array(3) {
[0]=>
string(3) "abc"
[1]=>
string(3) "abc"
[2]=>
bool(false) // <-- "bool"(false) : mb_ereg()
}
如果在模式末尾添加 ".*" 返回 "false"
而只有一个 "." 返回 "true"
怀疑字符串对于模式匹配来说太长了。
在这种情况下,使用 preg_match() 在放置 ".*" 时返回 "true"
,但添加更多 "$" 或 "\z" 返回 "false",正如预期的那样。
使用命名子模式的 mb_ereg()
永远不会捕获非命名子模式。
(Oniguruma 的限制)
<?php
$str = 'abcdefg';
$patternA = '\A(abcd)(.*)\z'; // 都捕获 [1]abcd [2]efg
$patternB = '\A(abcd)(?<rest>.*)\z'; // 非命名的 'abcd' 永远不会被捕获
mb_ereg($patternA, $str, $match);
echo '<pre>'.print_r($match, true).'</pre>';
mb_ereg($patternB, $str, $match);
echo '<pre>'.print_r($match, true).'</pre>';
?>
Array
(
[0] => abcdefg
[1] => abcd
[2] => efg
)
Array
(
[0] => abcdefg
[1] => efg
[rest] => efg
)
<?php
# mb_ereg() 的返回值和 $_3rd_argument 的变化
# (直接运行这个脚本)
function dump2str($var) {
ob_start();
var_dump($var);
$output = ob_get_contents();
ob_end_clean();
return $output;
}
# (PHP7) 空模式返回 bool(false) 并发出警告
# (PHP8) 空模式抛出 ValueError
$emp_ptn = '';
try{
$emp_ptn.= dump2str(mb_ereg('', 'abcde'));
}catch(Exception | Error $e){
$emp_ptn.= get_class($e).'<br>';
$emp_ptn.= $e->getMessage();
$emp_ptn.= '<pre>'.$e->getTraceAsString().'</pre>';
}
echo
'PHP '.phpversion().'<br><br>'.
'# 匹配<br>'.
dump2str(mb_ereg("bcd", "abcde")).
' : mb_ereg("bcd", "abcde")<br><br>'.
'# 匹配并使用第三个参数<br>'.
dump2str(mb_ereg("bcd", "abcde", $_3rd)).
' : mb_ereg("bcd", "abcde", $_3rd) // '.dump2str($_3rd).'<br><br>'.
'# 匹配 (0 字节)<br>'.
dump2str(mb_ereg("^", "abcde")).
' : mb_ereg("^", "abcde")<br><br>'.
'# 匹配 (0 字节) 并使用第三个参数<br>'.
dump2str(mb_ereg("^", "abcde", $_3rd)).
' : mb_ereg("^", "abcde", $_3rd) // '.dump2str($_3rd).'<br><br>'.
'# 不匹配<br>'.
dump2str(mb_ereg("f", "abcde")).
' : mb_ereg("f", "abcde")<br><br>'.
'# 不匹配并使用第三个参数<br>'.
dump2str(mb_ereg("f", "abcde", $_3rd)).
' : mb_ereg("f", "abcde", $_3rd) // '.dump2str($_3rd).'<br><br>'.
'# 空模式<br>'.
$emp_ptn.
' : mb_ereg("", "abcde")<br><br>'.
'# 空模式并使用第三个参数<br>'.
$emp_ptn.
' : mb_ereg("", "abcde", $_3rd) // '.dump2str($_3rd).'<br><br>';
?>
我希望这些信息可以在 php.net 上找到。
根据 "https://github.com/php/php-src/tree/PHP-5.6/ext/mbstring/oniguruma",
捆绑的 Oniguruma 正则表达式库版本似乎是...
PHP 5.3 - 5.4.45 之间为 4.7.1,
PHP 5.5 - 7.1.16 之间为 5.9.2,
PHP 7.2 及以上版本为 6.3.0。
mb_ereg() 似乎无法使用“命名子模式”。
preg_match() 似乎只在 UTF-8 编码中可以替代。
<?php
$text = 'multi_byte_string';
$pattern = '.*(?<name>string).*'; // "?P" 在 PHP 5.3.5 中会导致 "mbregex compile err"
if(mb_ereg($pattern, $text, $matches)){
echo '<pre>'.print_r($matches, true).'</pre>';
}else{
echo 'no match';
}
?>
这段代码会忽略 $pattern 中的 "?<name>" 并显示以下内容。
Array
(
[0] => multi_byte_string
[1] => string
)
$pattern = '/.*(?<name>string).*/u';
if(preg_match($pattern, $text, $matches)){
替换第 2 行和第 3 行
显示以下内容(在 UTF-8 编码中)。
Array
(
[0] => multi_byte_string
[name] => string
[1] => string
)
<?php
// 在 PHP_VERSION 7.1 中
// 没有 $regs (第三个参数)
$int = mb_ereg('abcde', '_abcde_'); // [5 字节匹配]
var_dump($int); // int(1)
$int = mb_ereg('ab', '_ab_'); // [2 字节匹配]
var_dump($int); // int(1)
$int = mb_ereg('^', '_ab_'); // [0 字节匹配]
var_dump($int); // int(1)
$int = mb_ereg('ab', '__'); // [不匹配]
var_dump($int); // bool(false)
$int = mb_ereg('', '_ab_'); // [错误:空模式]
// Warning: mb_ereg(): empty pattern in ...
var_dump($int); // bool(false)
$int = mb_ereg('ab'); // [错误:参数不足]
// Warning: mb_ereg() expects at least 2 parameters, 1 given in ...
var_dump($int); // bool(false)
// 没有第三个参数,mb_ereg() 返回 int(1) 或 bool(false)。
// 有 $regs (第三个参数)
$int = mb_ereg('abcde', '_abcde_', $regs);// [5 字节匹配]
var_dump($int); // int(5)
var_dump($regs); // array(1) { [0]=> string(5) "abcde" }
$int = mb_ereg('ab', '_ab_', $regs); // [2 字节匹配]
var_dump($int); // int(2)
var_dump($regs); // array(1) { [0]=> string(2) "ab" }
$int = mb_ereg('^', '_ab_', $regs); // [0 字节匹配]
var_dump($int); // int(1)
var_dump($regs); // array(1) { [0]=> bool(false) }
$int = mb_ereg('ab', '__', $regs); // [不匹配]
var_dump($int); // bool(false)
var_dump($regs); // array(0) { }
$int = mb_ereg('', '_ab_', $regs); // [错误:空模式]
// Warning: mb_ereg(): empty pattern in ...
var_dump($int); // bool(false)
var_dump($regs); // array(0) { }
$int = mb_ereg('ab'); // [错误:参数不足]
// Warning: mb_ereg() expects at least 2 parameters, 1 given in ...
var_dump($int); // bool(false)
var_dump($regs); // array(0) { }
// 有第三个参数,mb_ereg() 返回 int(匹配的字节数) 或 bool(false)
// 而且第三个参数比较复杂。
?>
虽然很少被提及,但值得注意的是 mb_ereg 在内部使用 Oniguruma 库。默认模式(ruby)的语法在此处描述
http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt
希伯来语正则表达式在 PHP 5,Ubuntu 8.04 上测试。
似乎在没有 mb_regex_encoding 行(已注释掉)的情况下工作正常。
似乎不适用于 \uxxxx(也已注释掉)。
<?php
echo "Line ";
//mb_regex_encoding("ISO-8859-8");
//if(mb_ereg(".*([\u05d0-\u05ea]).*", $this->current_line))
if(mb_ereg(".*([א-ת]).*", $this->current_line))
{
echo "has";
}
else
{
echo "doesn't have";
}
echo " Hebrew characters.<br>";
//mb_regex_encoding("UTF-8");
?>