preg_match_all项目名称和描述

时间:2017-06-26 18:09:48

标签: php regex preg-match-all

我有一个.txt文件,其中包含 CAN 的一些数据:

MyItem2_item_name=Nice Title
MyItem2_item_desc=A short description

item_name

注意:有时只有item_desc但没有MyItem1

我想匹配

  • desc
  • 如果是name =
  • Array ( [0] => Array ( [0] => item_name_MyItem1=Nice Title [1] => name [2] => MyItem1 [3] => Nice Title ) [1] => Array ( [0] => item_desc_MyItem1=A short description [1] => desc [2] => MyItem1 [3] => A short description ) [2] => Array ( [0] => MyItem2_item_name=Nice Title [1] => name [2] => MyItem2 [3] => Nice Title ) [3] => Array ( [0] => MyItem2_item_desc=A short description [1] => desc [2] => MyItem2 [3] => A short description ) // For example: MyItem3 only has a item_name [4] => Array ( [0] => item_name_MyItem3=Nice Title [1] => name [2] => MyItem3 [3] => Nice Title ) )
  • 之后的所有内容

所以预期的结果是:

~(?:(.*)_)?item_(name|desc)(?:_(.*))?=(.*)~i'

到目前为止,我有这个正则表达式:PREG_SET_ORDER我将它用于(?:(.*)_)?

这个正则表达式的问题是,由于选项(?:_(.*))?和{{1}},它在每个数组上都有一个空值。

希望有人可以帮我修复这个正则表达式,所以它符合我的预期结果。

3 个答案:

答案 0 :(得分:3)

逐行读取文件并将其拆分为=

$handle = fopen("inputfile.txt", "r");
$results = [];

if ($handle) {
    while (($line = fgets($handle)) !== false) {
        list($name, $desc) = explode('=', $line);

        $results[] = [
            $line,
            strpos($name, 'name') !== false ? 'name' : 'desc',
            $name,
            $desc
        ];
    }

    fclose($handle);
} else {
    // error opening the file.
} 

答案 1 :(得分:0)

Justinas'答案让我感到困惑。看起来它应该不起作用,所以我会发布一些我认为可以做的事情。

$handle=fopen("inputfile.txt","r");
if($handle){
    while(($line=fgets($handle))!==false){
        $dyad=explode("=",$line);  // split in two parts
        $attrs=explode("_",$dyad[0]);  // split the first part into 3 parts
        if(strpos('item',$attrs[0])===0){
            $result[]=[$attrs[2],$attrs[1],$dyad[1]];
        }else{
            $result[]=[$attrs[0],$attrs[2],$dyad[1]];
        }
    }
    var_export($result);
    fclose($handle);
}

这是demo link with some test data

答案 2 :(得分:-1)

第一个可选部分中删除内部捕获组:

(.*) => .*

所以你有:

~(?:.*_)?item_(name|desc)(?:_(.*))?=(.*)~i

但你可以完全删除那个前缀,因为无论如何它都是可选的,你没有什么东西可以捕获:

~item_(name|desc)(?:_(.*))?=(.*)~i