根据 php 中没有正则表达式的模式格式化字符串
Formatting string according to pattern without regex in php
如何根据灵活的模式格式化任意字符串?我想到的唯一解决方案是使用正则表达式,但我需要 2 "patterns"(一个用于搜索,一个用于输出)。
示例:
$str = '123ABC5678";
期望输出:12.3AB-C5-67.8
我想在变量中使用一个模式(用户可以在不了解正则表达式的情况下轻松定义的模式)它可能看起来像这样:
$pattern = '%%.%%%-%%-%%.%';
因此用户只需使用 2 个不同的字符(% 和 .)
使用正则表达式的解决方案如下所示:
$str = '123ABC5678';
$pattern_src = '@(.{2})(.{3})(.{2})(.{2})(.{1})@';
$pattern_rpl = ".--.";
$res = preg_replace($pattern_src, $pattern_rpl, $str);
//$res eq 12.3AB-C5-67.8
太复杂了,因为用户需要定义 $pattern_src 和 $pattern_rpl。如果字符串的长度可以变化,解释起来会更复杂。
是的,我可以编写一个 function/parser 来构建基于简单用户模式(如 %%.%%%-%%-%%.%)所需的正则表达式。但我想知道是否有任何 "built in" 方法可以用 php 实现这一点?我在考虑 sprintf 等,但这似乎并不能解决问题。有什么想法吗?
为什么不编写一个简单的解析器,其工作方式如下:
对于模式的每个字符:
- 如果你匹配百分号字符,输出输入的下一个字符
- 如果匹配到任何其他字符,则输出它
$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;
I was thinking about sprintf etc., but that doesn't seem to do the trick.
你走在正确的轨道上。您可以使用 vsprintf
完成此操作,如下所示:
$str = '123ABC5678';
$pattern = '%%.%%%-%%-%%.%';
echo vsprintf(str_replace('%', '%s', $pattern), str_split($str));
输出:
12.3AB-C5-67.8
这是假设 $pattern
中的 %
个字符的数量与 $str
的长度匹配。
如何根据灵活的模式格式化任意字符串?我想到的唯一解决方案是使用正则表达式,但我需要 2 "patterns"(一个用于搜索,一个用于输出)。
示例:
$str = '123ABC5678";
期望输出:12.3AB-C5-67.8
我想在变量中使用一个模式(用户可以在不了解正则表达式的情况下轻松定义的模式)它可能看起来像这样:
$pattern = '%%.%%%-%%-%%.%';
因此用户只需使用 2 个不同的字符(% 和 .)
使用正则表达式的解决方案如下所示:
$str = '123ABC5678';
$pattern_src = '@(.{2})(.{3})(.{2})(.{2})(.{1})@';
$pattern_rpl = ".--.";
$res = preg_replace($pattern_src, $pattern_rpl, $str);
//$res eq 12.3AB-C5-67.8
太复杂了,因为用户需要定义 $pattern_src 和 $pattern_rpl。如果字符串的长度可以变化,解释起来会更复杂。
是的,我可以编写一个 function/parser 来构建基于简单用户模式(如 %%.%%%-%%-%%.%)所需的正则表达式。但我想知道是否有任何 "built in" 方法可以用 php 实现这一点?我在考虑 sprintf 等,但这似乎并不能解决问题。有什么想法吗?
为什么不编写一个简单的解析器,其工作方式如下:
对于模式的每个字符:
- 如果你匹配百分号字符,输出输入的下一个字符
- 如果匹配到任何其他字符,则输出它
$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;
I was thinking about sprintf etc., but that doesn't seem to do the trick.
你走在正确的轨道上。您可以使用 vsprintf
完成此操作,如下所示:
$str = '123ABC5678';
$pattern = '%%.%%%-%%-%%.%';
echo vsprintf(str_replace('%', '%s', $pattern), str_split($str));
输出:
12.3AB-C5-67.8
这是假设 $pattern
中的 %
个字符的数量与 $str
的长度匹配。