Как я могу отформатировать произвольную строку в соответствии с гибким шаблоном? Единственное решение, которое я придумал, это использование регулярных выражений, но тогда мне нужно 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? Я думал о спринте и т. Д., Но, похоже, это не сработало. Есть идеи?
Я думал о спринте и т. Д., Но, похоже, это не сработало.
Вы на правильном пути. Вы можете сделать это с vsprintf
следующее:
$str = '123ABC5678';
$pattern = '%%.%%%-%%-%%.%';
echo vsprintf(str_replace('%', '%s', $pattern), str_split($str));
Выход:
12.3AB-C5-67.8
Это при условии, что количество %
персонажи в $pattern
соответствовать длине $str
,
Почему бы не написать простой парсер, который работает следующим образом:
Для каждого символа шаблона:
$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;
У меня есть похожее решение, которое выглядит следующим образом.
<?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.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;