PHP Conference Japan 2024

mb_ereg

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

mb_ereg支持多字节的正则表达式匹配

描述

mb_ereg(字符串 $pattern, 字符串 $string, 数组 &$matches = null): 布尔值

执行支持多字节的正则表达式匹配。

参数

pattern

搜索模式。

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 设置为空数组。以前,在这种情况下 matches 不会被修改。

备注

注意:

内部编码或由 mb_regex_encoding() 指定的字符编码将用作此函数的字符编码。

参见

  • mb_regex_encoding() - 设置/获取多字节正则表达式的字符编码
  • mb_eregi() - 不区分大小写的正则表达式匹配,支持多字节

添加注释

用户贡献的注释 12 条注释

3
匿名
3 年前
preg_match() 和 mb_ereg() 之间的一个区别
关于“捕获的带括号的子模式”。

<?php

preg_match
('/(abc)(.*)/', 'abc', $match);
var_dump($match);

mb_ereg('(abc)(.*)', 'abc', $match);
var_dump($match);

?>

数组(3) {
[0]=>
字符串(3) "abc"
[1]=>
字符串(3) "abc"
[2]=>
字符串(0) "" // <-- "字符串"(0) "" : preg_match()
}

数组(3) {
[0]=>
字符串(3) "abc"
[1]=>
字符串(3) "abc"
[2]=>
布尔值(false) // <-- "布尔值"(false) : mb_ereg()
}
5
匿名
7 年前
到 Oniguruma 正则表达式语法的旧链接不再有效,有一个有效的链接
https://github.com/geoffgarside/oniguruma/blob/master/Syntax.txt
2
pressler at hotmail dot de
12 年前
请注意,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
"文本不包含阿拉伯语/希伯来语字符。";
}

?>
0
匿名
1 个月前
mb_ereg() 无法匹配超过 100,000(100K)个字符(不是字节而是字符)
而 preg_match() 可以超过 1,000,000,000(1G,如果它在“memory_limit”范围内)。
试试这个。

<?php

ini_set
("memory_limit", "512M"); // <-- 如果尝试 1G,则必须更改。
$length = 100000; // <-- 99999 可以 / 100000 不行

$str = "";
for (
$i=0; $i<$length; $i++):
$str .= "1"; // <-- 如果它是多字节字符,则结果相同。
endfor;

if (
mb_ereg('.*', $str)):
echo
'<br><span style="background-color:lightgreen">OK!</span><br>memory_limit = '.ini_get("memory_limit").'<br>$length = '.$length;
else:
echo
'<br><span style="background-color:orange">NG!</span><br>memory_limit = '.ini_get("memory_limit").'<br>$length = '.$length;
endif;

?>
0
匿名
2 年前
如果在模式末尾添加“.*”返回“false”
而只有一个“.”返回“true”,

怀疑字符串对于模式匹配来说太长了。

在这种情况下,使用 preg_match() 在放置“.*”时返回“true”
,但添加更多“$”或“\z”将按预期返回“false”。
0
匿名
3 年前
带有名称子模式的 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>';
?>

数组
(
[0] => abcdefg
[1] => abcd
[2] => efg
)

数组
(
[0] => abcdefg
[1] => efg
[rest] => efg
)
0
匿名用户
3 年前
<?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>';

?>
0
lastuser at example dot com
6 年前
我希望这些信息可以在 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。
0
mb_ereg() 似乎无法使用“命名子模式”
9 年前
mb_ereg() 似乎无法使用“命名子模式”。
preg_match() 似乎只是在 UTF-8 编码中可以替代。

<?php

$text
= 'multi_byte_string';
$pattern = '.*(?<name>string).*'; // 在 PHP 5.3.5 中,“?P” 会导致“mbregex 编译错误”

if(mb_ereg($pattern, $text, $matches)){
echo
'<pre>'.print_r($matches, true).'</pre>';
}else{
echo
'无匹配';
}

?>

此代码忽略了 $pattern 中的“?<name>” 并显示以下内容。

数组
(
[0] => multi_byte_string
[1] => string
)

$pattern = '/.*(?<name>string).*/u';
if(preg_match($pattern, $text, $matches)){

替换第 2 行和第 3 行
显示以下内容(在 UTF-8 编码中)。

数组
(
[0] => multi_byte_string
[name] => string
[1] => string
)
-1
匿名用户
5 年前
<?php

// 在 PHP 版本 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)
// 并且第三个参数比较复杂。

?>
-2
Riikka K
10 年前
虽然很少在任何地方提及,但需要注意的是 mb_ereg 在内部使用 Oniguruma 库。默认模式(ruby)的语法在此处描述

http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt
-2
Jon
15 年前
在 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");
?>
To Top