preg_split如何使用php将分隔符转换为索引

时间:2017-04-30 22:45:51

标签: php regex preg-split

我在PHP中使用字符串的情况: *nJohn*sSmith*fGeorge#*nHenry*sFord 并希望用

创建一个数组

[name],[surname],[fathers]作为索引,因此它将产生

name_array[1] = (
   [name] => 'John',
   [surname] => 'Smith',
   [fathers] => 'George'
)
name_array[2]=(
   [name] => 'Henry',
   [surname] => 'Ford'
) 

等等。 如何在PHP中使用preg_split? 谢谢!

5 个答案:

答案 0 :(得分:1)

我使用preg_match_all来获取姓名。如果你的字符串是一致的,我认为你可以这样做:

$string = '*nJohn*sSmith*fGeorge#*nHenry*sFord';
preg_match_all('/\*n(?<givenname>.*?)\*s(?<surname>.*?)(?:\*f(?<middlename>.*?))?(?:#|$)/', $string, $matches);
print_r($matches);

正则表达式演示:https://regex101.com/r/1hKzvM/1/

PHP演示:https://eval.in/784879

答案 1 :(得分:1)

不使用正则表达式的解决方案:

$string = '*nJohn*sSmith*fGeorge#*nHenry*sFord';
$result = array();
$persons = explode('#', $string);
foreach ($persons as $person) {
    $identials = explode('*', $person);
    unset($r);
    foreach ($identials as $idential) {
        if(!$idential){
            continue;   //empty string
        }
        switch ($idential[0]) { //first character
            case 'n':
                $key = 'name';
                break;
            case 's':
                $key = 'surename';
                break;
            case 'f':
                $key = 'fathers';
                break;
        }
        $r[$key] = substr($idential, 1);
    }
    $result[] = $r;
}

答案 2 :(得分:1)

此功能将产生您想要的结果!但请注意,这不是唯一的方式,而不是100%正确的方式!我问你使用preg_split

function splitMyString($str){

 $array_names = [];

 $mainString =   explode('#', $str);  

 $arr1 = preg_split("/\*[a-z]/", $mainString[0]);

 unset($arr1[0]);
 $arr1_values = array_values($arr1);
 $arr1_keys = ['name','surname','fathers'];
 $result1 = array_combine($arr1_keys, $arr1_values);


 // second part of string
 $arr2 = preg_split("/\*[a-z]/", $mainString[1]);

 unset($arr2[0]);
 $arr2_values = array_values($arr2);
 $arr2_keys = ['name','surname'];
 $arr2 = array_combine($arr2_keys, $arr2_values);

 $array_names[] = $arr1;
 $array_names[] = $arr2;

 return $array_names;
}

// test result !
print_r(splitMyString("*nJohn*sSmith*fGeorge#*nHenry*sFord"));

答案 3 :(得分:0)

感谢所有人! 出于某种原因,该网站阻止了我对某些“声誉”原因的投票,我认为这并不完全符合民主!另一方面,谁关心民主这些天! 然而,我使用的是解决方案#2,没有说明解决方案1或3不是很好! 问候。

然而,受到你的回答的启发,我也想到了我的,就在这里!

$string = '*nJohn*sSmith*fGeorge#*nHenry*sFord';
split_to_key ( $string, array('n'=>'Name','s'=>'Surname','f'=>'Middle'));

function split_to_key ( $string,$ind=array() )
{
        $far=null;
        $i=0;

        $fbig=preg_split('/#/',$string,-1,PREG_SPLIT_NO_EMPTY);

        foreach ( $fbig as $fsmall ) {

                $f=preg_split('/\*/u',$fsmall,-1,PREG_SPLIT_NO_EMPTY);

                foreach ( $f as $fs ) {
                        foreach( array_keys($ind) as $key  ) {
                                if( preg_match ('/^'.$key.'/u',$fs ) ) {
                                        $fs=preg_replace('/^'.$key.'/u','',$fs);
                                        $far[$i][$ind[$key]]=$fs;
                                }
                        }
                }
                $i++;
        }
        print_r($far);
}

答案 4 :(得分:0)

像克里斯一样,我不会使用preg_split()。我的方法只使用一个preg()函数和一个循环来完全准备所需格式的过滤输出(注意我的输出是0索引的。)

输入(我扩展了输入样本以进行测试):

$string='*nJohn*sSmith*fGeorge#*nHenry*sFord#*nJames*sWashington#*nMary*sMiller*fRichard';

方法(PHP Demo&amp; Regex Demo):

if(preg_match_all('/\*n([^*]*)\*s([^*]*)(?:\*f([^#]*))?(?=#|$)/', $string, $out)){
    $out=array_slice($out,1);  // /prepare for array_column()
    foreach($out[0] as $i=>$v){
        $name_array[$i]=array_combine(['name','surname','father'],array_column($out,$i));
        if($name_array[$i]['father']==''){unset($name_array[$i]['father']);}
    }
}
var_export($name_array);

输出:

array (
  0 => 
  array (
    'name' => 'John',
    'surname' => 'Smith',
    'father' => 'George',
  ),
  1 => 
  array (
    'name' => 'Henry',
    'surname' => 'Ford',
  ),
  2 => 
  array (
    'name' => 'James',
    'surname' => 'Washington',
  ),
  3 => 
  array (
    'name' => 'Mary',
    'surname' => 'Miller',
    'father' => 'Richard',
  ),
)

我的正则表达式模式通过使用“负字符类”来优化速度。我选择不使用命名的捕获组,因为它们几乎使preg_match_all()的输出数组大小加倍,并且该数组无论如何都需要进一步准备。