2024 年 PHP 日本研討會

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 (10 萬) 個字元(不是位元組,而是字元)
而 preg_match() 可以在「memory_limit」允許的情況下匹配超過 1,000,000,000 (10 億) 個字元。
試試這個。

<?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">成功!</span><br>memory_limit = '.ini_get("memory_limit").'<br>$length = '.$length;
else:
echo
'<br><span style="background-color:orange">失敗!</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

# What mb_ereg() returns & changes $_3rd_argument into
# (Just run this script)

function dump2str($var) {
ob_start();
var_dump($var);
$output = ob_get_contents();
ob_end_clean();
return
$output;
}

# (PHP7)empty pattern returns bool(false) with Warning
# (PHP8)empty pattern throws 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>'.

'# match<br>'.
dump2str(mb_ereg("bcd", "abcde")).
' : mb_ereg("bcd", "abcde")<br><br>'.

'# match with 3rd argument<br>'.
dump2str(mb_ereg("bcd", "abcde", $_3rd)).
' : mb_ereg("bcd", "abcde", $_3rd) // '.dump2str($_3rd).'<br><br>'.

'# match (0 byte)<br>'.
dump2str(mb_ereg("^", "abcde")).
' : mb_ereg("^", "abcde")<br><br>'.

'# match (0 byte) with 3rd argument<br>'.
dump2str(mb_ereg("^", "abcde", $_3rd)).
' : mb_ereg("^", "abcde", $_3rd) // '.dump2str($_3rd).'<br><br>'.

'# unmatch<br>'.
dump2str(mb_ereg("f", "abcde")).
' : mb_ereg("f", "abcde")<br><br>'.

'# unmatch with 3rd argument<br>'.
dump2str(mb_ereg("f", "abcde", $_3rd)).
' : mb_ereg("f", "abcde", $_3rd) // '.dump2str($_3rd).'<br><br>'.

'# empty pattern<br>'.
$emp_ptn.
' : mb_ereg("", "abcde")<br><br>'.

'# empty pattern with 3rd argument<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」,
PHP 綁定的 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).*'; // "?P" 在 PHP 5.3.5 中會造成 "mbregex compile err"

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

// in PHP_VERSION 7.1

// WITHOUT $regs (3rd argument)
$int = mb_ereg('abcde', '_abcde_'); // [5 bytes match]
var_dump($int); // int(1)

$int = mb_ereg('ab', '_ab_'); // [2 bytes match]
var_dump($int); // int(1)

$int = mb_ereg('^', '_ab_'); // [0 bytes match]
var_dump($int); // int(1)

$int = mb_ereg('ab', '__'); // [not match]
var_dump($int); // bool(false)

$int = mb_ereg('', '_ab_'); // [error : empty pattern]
// Warning: mb_ereg(): empty pattern in ...
var_dump($int); // bool(false)

$int = mb_ereg('ab'); // [error : fewer arguments]
// Warning: mb_ereg() expects at least 2 parameters, 1 given in ...
var_dump($int); // bool(false)

// Without 3rd argument, mb_ereg() returns either int(1) or bool(false).

// WITH $regs (3rd argument)
$int = mb_ereg('abcde', '_abcde_', $regs);// [5 bytes match]
var_dump($int); // int(5)
var_dump($regs); // array(1) { [0]=> string(5) "abcde" }

$int = mb_ereg('ab', '_ab_', $regs); // [2 bytes match]
var_dump($int); // int(2)
var_dump($regs); // array(1) { [0]=> string(2) "ab" }

$int = mb_ereg('^', '_ab_', $regs); // [0 bytes match]
var_dump($int); // int(1)
var_dump($regs); // array(1) { [0]=> bool(false) }

$int = mb_ereg('ab', '__', $regs); // [not match]
var_dump($int); // bool(false)
var_dump($regs); // array(0) { }

$int = mb_ereg('', '_ab_', $regs); // [error : empty pattern]
// Warning: mb_ereg(): empty pattern in ...
var_dump($int); // bool(false)
var_dump($regs); // array(0) { }

$int = mb_ereg('ab'); // [error : fewer arguments]
// Warning: mb_ereg() expects at least 2 parameters, 1 given in ...
var_dump($int); // bool(false)
var_dump($regs); // array(0) { }

// With 3rd argument, mb_ereg() returns either int(how many bytes matched) or bool(false)
// and 3rd argument is a bit complicated.

?>
-2
Riikka K
10 年前
雖然幾乎沒有任何地方提及,但值得注意的是,mb_ereg 內部使用 Oniguruma 函式庫。預設模式 (ruby) 的語法說明如下:

http://www.geocities.jp/kosako3/oniguruma/doc/RE.txt
-2
Jon
15 年前
在 Ubuntu 8.04 的 PHP 5 上測試的希伯來文正規表達式。
似乎在沒有 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