我有一个具有以下结构的字符串:
ABC_ABC_PQR_XYZ
PQR具有以下结构:
ABC+JKL
和
ABC
本身是一个字符串,可以包含字母数字字符和一些其他字符,如“_”,“ - ”,“+”,“。”并且没有设置结构:
例如。qWe_rtY-asdf
或pkl123
所以,实际上,字符串可能如下所示:
qWe_rtY-asdf_qWe_rtY-asdf_qWe_rtY-asdf+JKL_XYZ
我的目标是找出构成ABC
的字符串。
我最初刚刚使用
$arrString = explode("_",$string);
在我意识到$arrString[0]
(ABC
)本身可以包含下划线之前返回$arrString[0]
,从而使其不正确。
我的下一次尝试无论如何都要在“_”上进行扩展,然后将每个爆炸的字符串部分与第一个字符串部分进行比较,直到我得到一个模式的外观:
function getPatternABC($string)
{
$count = 0;
$pattern ="";
$arrString = explode("_", $string);
foreach($arrString as $expString)
{
if(strcmp($expString,$arrString[0])!==0 || $count==0)
{
$pattern = $pattern ."_". $arrString[$count];
$count++;
}
else break;
}
return substr($pattern,1);
}
这很有效 - 但我想知道使用正则表达式是否有更优雅的方法吗?
答案 0 :(得分:1)
这是正则表达式解决方案:
'^([a-zA-Z0-9_+-]+)_\1_\1\+'
这样做是匹配(从字符串的开头开始)最长的序列,由方括号内的字符组成(根据您的规范编辑)。序列必须恰好出现两次,每次后跟一个下划线,然后必须再出现一个加号(这实际上是PQR
的前半部分,而JKL
之前的分隔符)。输入的其余部分将被忽略。
您会发现ABC
被捕获为捕获组1。
所以:
$input = 'qWe_rtY-asdf_qWe_rtY-asdf_qWe_rtY-asdf+JKL_XYZ';
$result = preg_match('/^([a-zA-Z0-9_+-]+)_\1_\1\+/', $input, $matches);
if ($result) {
echo $matches[2];
}
答案 1 :(得分:1)
当然,只需创建一个与您的模式匹配的正则表达式。在这种情况下,像这样:
preg_match('/^([a-zA-Z0-9_+.-]+)_\1_\1\+JKL_XYZ$/', $string, $match);
你的ABC在$ match [1]。
答案 2 :(得分:0)
如果这些字符串中的下划线存在频率较低,则可能需要检查一下简单的explode()是否会在使用正则表达式之前执行此操作。
<?php
$str = 'ABC_ABC_PQR_XYZ';
if(substr_count($str, '_') == 3)
$abc = reset(explode('_', $str));
else
$abc = regexy_function($str);
?>