preg_replace_callback:在模式中包含花括号:{ 被捕获,} 不是
preg_replace_callback: including curly braces in a pattern: { is captured, } isn't
我有这个功能,它利用 preg_replace_callback 将一个句子分成 "chains" 个属于不同类别(字母、汉字、其他所有字符)的块。
该函数还试图包含字符 ' 、 { 和 }作为 "alphabetic"
function String_SplitSentence($string)
{
$res = array();
preg_replace_callback("~\b(?<han>\p{Han}+)\b|\b(?<alpha>[a-zA-Z0-9{}']+)\b|(?<other>[^\p{Han}A-Za-z0-9\s]+)~su",
function($m) use (&$res)
{
if (!empty($m["han"]))
{
$t = array("type" => "han", "text" => $m["han"]);
array_push($res,$t);
}
else if (!empty($m["alpha"]))
{
$t = array("type" => "alpha", "text" => $m["alpha"]);
array_push($res, $t);
}
else if (!empty($m["other"]))
{
$t = array("type" => "other", "text" => $m["other"]);
array_push($res, $t);
}
},
$string);
return $res;
}
但是,花括号似乎有问题。
print_r(String_SplitSentence("Many cats{1}, several rats{2}"));
从输出中可以看出,该函数将 { 视为字母字符,如所示,但在 } 处停止并将其视为 "other"。
Array
(
[0] => Array
(
[type] => alpha
[text] => Many
)
[1] => Array
(
[type] => alpha
[text] => cats{1
)
[2] => Array
(
[type] => other
[text] => },
)
[3] => Array
(
[type] => alpha
[text] => several
)
[4] => Array
(
[type] => alpha
[text] => rats{2
)
[5] => Array
(
[type] => other
[text] => }
)
我做错了什么?
我不能完全确定,因为你的示例输入不代表任何汉字,我不知道你可能试图处理什么样的边缘案例,但我会这样写图案:
~(?<han>\p{Han}+)|(?<alpha>[a-z\d{}']+)|(?<other>\S+)~ui
\b
的问题在于它正在寻找 \w
个字符。 \w
代表大写字母、小写字母、数字、下划线。参考:
此外,您的模式不包含任何 .
,因此您可以删除 s
模式修饰符。
您的函数调用似乎也在滥用 preg_replace_callback()
。我的意思是,您实际上并没有替换任何东西,所以这是一个不恰当的调用。也许你可以考虑重写:
function String_SplitSentence($string){
if(!preg_match_all("~(?<han>\p{Han}+)|(?<alpha>[a-z\d{}']+)|(?<other>\S+)~ui",$string,$out)){
return []; // or $string or false
}else{
foreach($out as $group_key=>$group){
if(!is_numeric($group_key)){ // disregard the indexed groups (which are unavoidably generated)
foreach($group as $i=>$v){
if(strlen($v)){ // only store the value in the subarray that has a string length
$res[$i]=['type'=>$group_key,'text'=>$v];
}
}
}
}
ksort($res);
return $res;
}
}
关于您的模式的演示:https://regex101.com/r/6EUaSM/1
\b 在你的角色 class 搞砸之后。 }
未包含在 \w
class 中。正则表达式希望为您做好工作——它捕获 "greedily" 直到它不能再捕获。 }
由于单词边界而被排除在外。
我有这个功能,它利用 preg_replace_callback 将一个句子分成 "chains" 个属于不同类别(字母、汉字、其他所有字符)的块。
该函数还试图包含字符 ' 、 { 和 }作为 "alphabetic"
function String_SplitSentence($string)
{
$res = array();
preg_replace_callback("~\b(?<han>\p{Han}+)\b|\b(?<alpha>[a-zA-Z0-9{}']+)\b|(?<other>[^\p{Han}A-Za-z0-9\s]+)~su",
function($m) use (&$res)
{
if (!empty($m["han"]))
{
$t = array("type" => "han", "text" => $m["han"]);
array_push($res,$t);
}
else if (!empty($m["alpha"]))
{
$t = array("type" => "alpha", "text" => $m["alpha"]);
array_push($res, $t);
}
else if (!empty($m["other"]))
{
$t = array("type" => "other", "text" => $m["other"]);
array_push($res, $t);
}
},
$string);
return $res;
}
但是,花括号似乎有问题。
print_r(String_SplitSentence("Many cats{1}, several rats{2}"));
从输出中可以看出,该函数将 { 视为字母字符,如所示,但在 } 处停止并将其视为 "other"。
Array
(
[0] => Array
(
[type] => alpha
[text] => Many
)
[1] => Array
(
[type] => alpha
[text] => cats{1
)
[2] => Array
(
[type] => other
[text] => },
)
[3] => Array
(
[type] => alpha
[text] => several
)
[4] => Array
(
[type] => alpha
[text] => rats{2
)
[5] => Array
(
[type] => other
[text] => }
)
我做错了什么?
我不能完全确定,因为你的示例输入不代表任何汉字,我不知道你可能试图处理什么样的边缘案例,但我会这样写图案:
~(?<han>\p{Han}+)|(?<alpha>[a-z\d{}']+)|(?<other>\S+)~ui
\b
的问题在于它正在寻找 \w
个字符。 \w
代表大写字母、小写字母、数字、下划线。参考:
此外,您的模式不包含任何 .
,因此您可以删除 s
模式修饰符。
您的函数调用似乎也在滥用 preg_replace_callback()
。我的意思是,您实际上并没有替换任何东西,所以这是一个不恰当的调用。也许你可以考虑重写:
function String_SplitSentence($string){
if(!preg_match_all("~(?<han>\p{Han}+)|(?<alpha>[a-z\d{}']+)|(?<other>\S+)~ui",$string,$out)){
return []; // or $string or false
}else{
foreach($out as $group_key=>$group){
if(!is_numeric($group_key)){ // disregard the indexed groups (which are unavoidably generated)
foreach($group as $i=>$v){
if(strlen($v)){ // only store the value in the subarray that has a string length
$res[$i]=['type'=>$group_key,'text'=>$v];
}
}
}
}
ksort($res);
return $res;
}
}
关于您的模式的演示:https://regex101.com/r/6EUaSM/1
\b 在你的角色 class 搞砸之后。 }
未包含在 \w
class 中。正则表达式希望为您做好工作——它捕获 "greedily" 直到它不能再捕获。 }
由于单词边界而被排除在外。