为了账号安全,请及时绑定邮箱和手机立即绑定

需要优化:使用正则表达式使用可选且可重复的模式重新格式化字符串

需要优化:使用正则表达式使用可选且可重复的模式重新格式化字符串

PHP
慕田峪4524236 2023-09-08 16:46:02
我想使用正则表达式重新格式化 PHP 中的字符串。该字符串可以如下所示:(例如)bj-11_2008-06_2015(F01,F02,F03,F04) bj-11_2008-06_2015(F01) bj-11_2008-06_2015(01) bj-11_2008-06_2015(3B) bj-11_2008-06_2015bj-11_2008让我们看一下:第一部分是强制性的bj-11_2008,并且是bj固定的,11_2008可以是任何格式的日期MM_YYYY第二部分是可选的-06_2015,同样应该是MM_YYYY括号也是可选的(3B),但如果有的话,应该至少包含一个条目,但最多包含 n 个条目。每个条目最多应包含 4 个大写字母和/或数字,并用“,”分隔,例如:(F01,F02,F03,F04)。然后一切都应该像这样重新格式化:被bj-删除日期中的下划线“_”替换为竖线“|”破折号“-”周围有空格第二次日期后的空格用。。。来代替 ”;”输出示例:11|2008 - 06|2015 (F01;F02;F03;F04)这是我已经得到的:正则表达式:bj-([0-9]{2})_([0-9]{4})[-]*([0-9]{2})?_?([0-9]{4})?([(]([[:alnum:]]{0,4},?)*[)])?https://regex101.com/r/R7R3jC/1PHP:$regex = "/bj-([0-9]{2})_([0-9]{4})[-]*([0-9]{2})?_?([0-9]{4})?([(]([[:alnum:]]{0,4},?)*[)])?/";$teststrings=array(        "bj-11_2008-06_2015(F01,F02,F03,F04)",        "bj-11_2008-06_2015(F01)",        "bj-11_2008-06_2015(01)",        "bj-11_2008-06_2015(3B)",        "bj-11_2008-06_2015",        "bj-11_2008"    );foreach ($teststrings as $teststring) {    echo preg_replace_callback($regex, function($matches) {            $regexp2 = "/([[:alnum:]]{0,4},?)/";            $string ="";                        if (isset($matches[5])) {                $string = "(";                preg_match_all($regexp2, $matches[5], $inner_matches, PREG_SET_ORDER);                                foreach($inner_matches as $match){                    $string .= "$match[0]";                }                $string .= ")";                $string = str_replace(",",";",$string);            }                        if (isset($matches[4])){                echo "$matches[1]|$matches[2] - $matches[3]|$matches[4]" . " $string<br>";            }             else {                echo "$matches[1]|$matches[2]";            }        }    , $teststring);}http://sandbox.onlinephpfunctions.com/code/12b77482508f9d41e8b27a8c4df57bf47914155e这是可行的,但我认为相对复杂,可能可以简化和优化。但这是我用我对正则表达式非常有限的知识所能做出的全部,你能帮助我吗?
查看完整描述

2 回答

?
largeQ

TA贡献2039条经验 获得超7个赞

由于您的原始字符串已经格式化并且此格式是已知的,因此您无需使用正则表达式模式来探索它,您可以通过简单的替换来完成:


$s = <<<'EOD'

bj-11_2008-06_2015(F01,F02,F03,F04)

bj-11_2008-06_2015(F01)

bj-11_2008-06_2015(01)

bj-11_2008-06_2015(3B)

bj-11_2008-06_2015

bj-11_2008

EOD;


$trans = [ 'bj-' => '', '_' => '|', '-' => ' - ', '(' => ' (',

           ',' => ';' ];


echo strtr($s, $trans);


演示


查看完整回答
反对 回复 2023-09-08
?
慕桂英4014372

TA贡献1871条经验 获得超13个赞

没有任何正则表达式,仅使用一些子字符串:


$input='bj-11_2008-06_2015(F01,F02,F03,F04)';


$s1=$s2=$s3='';


$sub = substr($input,3,7);                // => 11_2008

$s1 = str_replace('_','|',$sub);          // => 11|2008


$sub = substr($input,11,7);               // => 06_2015

if($sub !== false){

   $s2 = ' - '.str_replace('_','|',$sub); // => - 06|2015

   }


$sub = substr($input,18);                 // => (F01,F02,F03,F04)

if($sub !== false){

   $s3 = str_replace(',',';',$sub);       // =>  (F01;F02;F03;F04)

   }


$result = $s1.$s2.$s3;                    // => 11|2008 - 06|2015 (F01;F02;F03;F04)


查看完整回答
反对 回复 2023-09-08
  • 2 回答
  • 0 关注
  • 66 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信