One of the differences between preg_match() & mb_ereg()
about "captured parenthesized subpattern".
<?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()
}mb_ereg
Почист и полокален преглед на PHP референцата, со задржана структура од PHP.net и подобра читливост за примери, секции и белешки.
mb_ereg
Референца за `function.mb-ereg.php` со подобрена типографија и навигација.
mb_ereg
(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)
mb_ereg — Регуларен израз натпревар со поддршка за повеќе бајти
= NULL
Извршува натпревар на регуларен израз со поддршка за повеќе бајти.
Параметри
pattern-
Низата за пребарување.
string-
Пребарувањето string.
matches-
Ако се најдат натпревари за поднизи во загради од
patternи функцијата се повикува со третиот аргументmatches, натпреварите ќе бидат зачувани во елементите на низатаmatches. Ако не се најдат натпревари,matchesсе поставува на празна низа.$matches[1] ќе ја содржи поднизата што започнува од првата лева заграда; $matches[2] ќе ја содржи поднизата што започнува од втората, и така натаму. $matches[0] ќе содржи копија од целиот натпревар на низата.
Вратени вредности
Враќа дали pattern matches string.
Дневник на промени
| Верзија | = NULL |
|---|---|
| 8.0.0 |
Оваа функција враќа true на успех сега. Претходно, враќаше должина во бајти на натпреварот ако натпревар за pattern беше пронајден во
string and matches беше предаден. Ако опционалниот параметар matches не беше предаден или должината на натпреварот беше 0, оваа функција врати 1.
|
| 7.1.0 |
mb_ereg() сега ќе постави matches на празно array, ако ништо не се совпадна. Порано,
matches не беше изменето во тој случај.
|
Белешки
Забелешка:
за објаснување. mb_regex_encoding() Внатрешно кодирање или кодирање на знаци специфицирано од
Види Исто така
- mb_regex_encoding() - Постави/земи ја кодировката на знаци за мултибајт регуларни изрази
- mb_eregi() - Регуларен израз што игнорира случај со поддршка за повеќе бајти
Белешки од корисници за да означиме кој било валиден PHP израз.
Old link to Oniguruma regex syntax is not working anymore, there is a working one:
https://github.com/geoffgarside/oniguruma/blob/master/Syntax.txtNote that mb_ereg() does not support the \uFFFF unicode syntax but uses \x{FFFF} instead:
<?PHP
$text = 'Peter is a boy.'; // english
$text = 'بيتر هو صبي.'; // arabic
//$text = 'פיטר הוא ילד.'; // hebrew
mb_regex_encoding('UTF-8');
if(mb_ereg('[\x{0600}-\x{06FF}]', $text)) // arabic range
//if(mb_ereg('[\x{0590}-\x{05FF}]', $text)) // hebrew range
{
echo "Text has some arabic/hebrew characters.";
}
else
{
echo "Text doesnt have arabic/hebrew characters.";
}
?>mb_ereg() cannot match over 100,000 (100K) characters (not bytes but characters)
whereas preg_match() can over 1,000,000,000 (1G, if it's within "memory_limit").
Try this.
<?php
ini_set("memory_limit", "512M"); // <-- must be changed if you try 1G.
$length = 100000; // <-- 99999 is OK / 100000 is NG
$str = "";
for ($i=0; $i<$length; $i++):
$str .= "1"; // <-- same result if it is a multibyte character.
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;
?>If adding ".*" at the end of the pattern returns "false"
whereas only one "." returns "true",
Suspect the string is too long for the pattern matching.
In this case, using preg_match() returns "true" when putting ".*"
, but adding more "$" or "\z" returns "false" as expected.mb_ereg() with a named-subpattern
never catches non-named-subpattern.
(Oniguruma's restriction)
<?php
$str = 'abcdefg';
$patternA = '\A(abcd)(.*)\z'; // both caught [1]abcd [2]efg
$patternB = '\A(abcd)(?<rest>.*)\z'; // non-named 'abcd' never caught
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
# 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>';
?>I hope this information is shown somewhere on php.net.
According to "https://github.com/php/php-src/tree/PHP-5.6/ext/mbstring/oniguruma",
the bundled Oniguruma regex library version seems ...
4.7.1 between PHP 5.3 - 5.4.45,
5.9.2 between PHP 5.5 - 7.1.16,
6.3.0 since PHP 7.2 - .mb_ereg() seems unable to Use "named subpattern".
preg_match() seems a substitute only in UTF-8 encoding.
<?php
$text = 'multi_byte_string';
$pattern = '.*(?<name>string).*'; // "?P" causes "mbregex compile err" in PHP 5.3.5
if(mb_ereg($pattern, $text, $matches)){
echo '<pre>'.print_r($matches, true).'</pre>';
}else{
echo 'no match';
}
?>
This code ignores "?<name>" in $pattern and displays below.
Array
(
[0] => multi_byte_string
[1] => string
)
$pattern = '/.*(?<name>string).*/u';
if(preg_match($pattern, $text, $matches)){
instead of lines 2 & 3
displays below (in UTF-8 encoding).
Array
(
[0] => multi_byte_string
[name] => string
[1] => string
)<?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.
?>While hardly mentioned anywhere, it may be useful to note that mb_ereg uses Oniguruma library internally. The syntax for the default mode (ruby) is described here:
http://www.geocities.jp/kosako3/oniguruma/doc/RE.txtHebrew regex tested on PHP 5, Ubuntu 8.04.
Seems to work fine without the mb_regex_encoding lines (commented out).
Didn't seem to work with \uxxxx (also commented out).
<?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");
?>