preg_replace_callback: включая фигурные скобки в шаблоне: {захватывается,} нет

У меня есть эта функция, которая использует preg_replace_callback, чтобы разбить предложение на «цепочки» блоков, принадлежащих к разным категориям (буквенные символы, символы хана, все остальное).

Функция пытается также включить символы , { , а также } как «буквенный»

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}"));

Как видно из выходных данных, функция обрабатывает {как буквенный символ, как указано, но останавливается на}, и вместо этого обрабатывает его как «другой».

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] => }
)

Что я делаю неправильно?

1

Решение

Я не могу быть полностью уверен, потому что ваш пример ввода не представляет никаких китайских символов, и я не знаю, какие дополнительные случаи вы можете пытаться обработать, но вот как я бы написал шаблон:

~(?<han>\p{Han}+)|(?<alpha>[a-z\d{}']+)|(?<other>\S+)~ui

Беда с \b это то, что он ищет \w персонажи. \w представляет заглавные буквы, строчные буквы, цифры и подчеркивания. Ссылка: https://stackoverflow.com/a/11874899/2943403

Также ваш шаблон не включает в себя .с, чтобы вы могли удалить 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 после того, как ваш класс персонажей запутался. } не входит в \w учебный класс. Regex хочет сделать хорошую работу для вас — он захватил «жадно», пока не может больше. } из-за границы слова.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]