Форматирование строки в соответствии с шаблоном без регулярных выражений в переполнении стека

Как я могу отформатировать произвольную строку в соответствии с гибким шаблоном? Единственное решение, которое я придумал, это использование регулярных выражений, но тогда мне нужно 2 «шаблона» (один для поиска и один для вывода).

Пример:

$str = '123ABC5678";

Желаемый выход: 12.3AB-C5-67.8

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

$pattern = '%%.%%%-%%-%%.%';

Таким образом, пользователь просто должен использовать 2 разных символа (% и.)

решение с регулярным выражением будет выглядеть так:

$str = '123ABC5678';
$pattern_src = '@(.{2})(.{3})(.{2})(.{2})(.{1})@';
$pattern_rpl = "$1.$2-$3-$4.$5";

$res = preg_replace($pattern_src, $pattern_rpl, $str);
//$res eq 12.3AB-C5-67.8

Слишком сложно, так как пользователю нужно будет определить $ pattern_src и $ pattern_rpl. Если бы строка могла варьироваться по длине, ее было бы еще сложнее объяснить.

Да, я мог бы написать функцию / анализатор, который создает необходимые регулярные выражения на основе простого пользовательского шаблона, такого как %%. %%% — %% — %%.%. Но мне интересно, есть ли какой-нибудь «встроенный» способ добиться этого с помощью php? Я думал о спринте и т. Д., Но, похоже, это не сработало. Есть идеи?

0

Решение

Я думал о спринте и т. Д., Но, похоже, это не сработало.

Вы на правильном пути. Вы можете сделать это с vsprintf следующее:

$str = '123ABC5678';
$pattern = '%%.%%%-%%-%%.%';
echo vsprintf(str_replace('%', '%s', $pattern), str_split($str));

Выход:

12.3AB-C5-67.8

Это при условии, что количество % персонажи в $pattern соответствовать длине $str,

1

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

Почему бы не написать простой парсер, который работает следующим образом:

Для каждого символа шаблона:

  • если вы соответствуете символу процента, выведите следующий символ из ввода
  • если вы соответствуете любому другому символу, выведите его

$str = '123ABC5678';
$pattern = '%%.%%%-%%-%%.%';

if (strlen($str) < substr_count($pattern, '%'))
Die('The length of input string is lower than number number of placeholders');
$len = strlen($pattern);
$stringIndex = 0;
$output = '';
for ($i = 0; $i < $len; $i++) {
if ($pattern[$i] === '%') {
$output .= $str[$stringIndex];
$stringIndex++;
} else {
$output .= $pattern[$i];
}
}
echo $output;
3

У меня есть похожее решение, которое выглядит следующим образом.

<?php
$format = '%%.%%%-%%-%%.%';
$string = '123ABC5678';

$new_string = '';
$c = 0;
for( $i = 0; $i < strlen( $format ); $i++ )
{
if( $format[ $i ] == '%' )
{
$new_string .= $string[ $c ];
$c++;
}
else
{
$new_string .= $format[ $i ];
}
}

echo $new_string;

Выход:

12.3AB-C5-67.8
2

Как насчет этого шаблона от пользователя?

2.3-2-2.1
Если шаблон представляет собой число означает n символов, точка или тире означает добавление точки или тире.

Теперь вы делаете регулярное выражение для анализа ввода пользователя:

preg_match_all("/(.)/", $User_input, $pattern);

Теперь у вас будет массив с числами, точками и тире.

Итак, переберите массив и соберите строку:

$string = '123ABC5678';
$User_input = "2.3-2-2.1";

preg_match_all("/(.)/", $User_input, $pattern);

$i=0;
$str="";
foreach($pattern[1] as $val){

if(is_numeric($val)){
$str .= substr($string,$i,$val);
$i=$i+$val;
}else{
$str .= $val;
}

}echo $str;

https://3v4l.org/5eg5G

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