2011-11-15 64 views
6

我有一个看起来很简单的问题,但却击败了我微不足道的正则表达式技巧。我有一个字符串,我需要转换为一个数组,然后相应地处理值,这很简单,但字符串的格式不能改变(它在别处生成),它的逻辑让我感到困惑。如何使用正则表达式将字符串拆分为二维数组?

该字符串是:

[6] [2] [3] 12.00; [5] [4] 

这基本上是一个组ID和十进制值(在这种情况下,ID 3 == 12.00)。 id的数量可以在任何时候改变,小数值可以在任何或全部id中。

在一个理想的世界里,我将有以下阵列:

Array (
    [0] => Array (
      [id] => 6 
      [num] => 
     ) 
    [1] => Array (
      [id] => 2 
      [num] => 
     ) 
    [2] => Array (
      [id] => 3 
      [num] => 12.00 
     ) 
    Etc... 

做任何你正则表达式向导知道如何可以用更少的脏话来完成,比我已经能够实现吗?

我迄今为止,已经能够提取使用的ID:

preg_match_all('@\[(.*?)\]@s', $string, $array); 

,并使用小数:

preg_match_all('/([0-9]+[,\.]{1}[0-9]{2})/', $string, $array); 

,但失去的ID和价值之间的关系。

+1

就可以解决这个问题,爆炸和它的strstr比在性能方面正则表达式更好。 – shox

回答

3

例子:

<?php 

$string = '[6] [2] [3] 12.00; [5] [4]'; 

preg_match_all('/\[(?P<id>\d+)\](?: (?P<num>[\d\.]+);)?/', $string, $matches, PREG_SET_ORDER); 

var_dump($matches); 

输出:

array(5) { 
    [0]=> 
    array(3) { 
    [0]=> 
    string(3) "[6]" 
    ["id"]=> 
    string(1) "6" 
    [1]=> 
    string(1) "6" 
    } 
    [1]=> 
    array(3) { 
    [0]=> 
    string(3) "[2]" 
    ["id"]=> 
    string(1) "2" 
    [1]=> 
    string(1) "2" 
    } 
    [2]=> 
    array(5) { 
    [0]=> 
    string(10) "[3] 12.00;" 
    ["id"]=> 
    string(1) "3" 
    [1]=> 
    string(1) "3" 
    ["num"]=> 
    string(5) "12.00" 
    [2]=> 
    string(5) "12.00" 
    } 
    [3]=> 
    array(3) { 
    [0]=> 
    string(3) "[5]" 
    ["id"]=> 
    string(1) "5" 
    [1]=> 
    string(1) "5" 
    } 
    [4]=> 
    array(3) { 
    [0]=> 
    string(3) "[4]" 
    ["id"]=> 
    string(1) "4" 
    [1]=> 
    string(1) "4" 
    } 
} 
+1

@戈登:完成并完成。感谢您的建议。 :) –

+0

这就是为什么我爱堆栈溢出 - 这绝对是完美的作品!非常感谢你! –

+1

@Matthew Chambers:不客气。 :) –

1

如果你是幸福的列表或者ID或NUM,那么你可以结合你的两个工作rege XES到一个通话中:

preg_match_all('@ \[(?P<id> \d+)] | (?P<num> [\d,.]+) @xs', 
     $string, $array, PREG_SET_ORDER); 

这会给你的关联数组列表,无论是idnum集,如果您还使用PREG_SET_ORDER标志。

1

像这样的东西?我的PHP技巧很弱,所以你必须检查如何访问指定的捕获组id/num

preg_match_all('/\[(?P<id>\d+)\]\s*(?P<num>[-+]?\b[0-9]+(?:\.[0-9]+)?\b)?/', $subject, $result, PREG_SET_ORDER); 
for ($matchi = 0; $matchi < count($result); $matchi++) { 
    for ($backrefi = 0; $backrefi < count($result[$matchi]); $backrefi++) { 
     # Matched text = $result[$matchi][$backrefi]; 
    } 
} 

工作原理:

" 
\[    # Match the character “[” literally 
(?<id>   # Match the regular expression below and capture its match into backreference with name “id” 
    \d    # Match a single digit 0..9 
     +    # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
) 
]    # Match the character “]” literally 
\s    # Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.) 
    *    # Between zero and unlimited times, as many times as possible, giving back as needed (greedy) 
(?<num>  # Match the regular expression below and capture its match into backreference with name “num” 
    [-+]   # Match a single character present in the list “-+” 
     ?    # Between zero and one times, as many times as possible, giving back as needed (greedy) 
    \b    # Assert position at a word boundary 
    [0-9]   # Match a single character in the range between “0” and “9” 
     +    # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
    (?:   # Match the regular expression below 
     \.    # Match the character “.” literally 
     [0-9]   # Match a single character in the range between “0” and “9” 
     +    # Between one and unlimited times, as many times as possible, giving back as needed (greedy) 
    )?    # Between zero and one times, as many times as possible, giving back as needed (greedy) 
    \b    # Assert position at a word boundary 
)?    # Between zero and one times, as many times as possible, giving back as needed (greedy) 
" 

它也需要负值的照顾。

0

它不是正则表达式的方法,但也许对你有用:(当然还可以提高)

$str = "[6] [2] [3] 12.00; [5] [4]"; 
$str = str_replace(array('[',']'), '', $str); 

$arr = explode(' ', $str); 
$array = array(); 
for($i=0 ; $i < count($arr) ; $i++) 
{ 
    $isValue = strpos($arr[$i], '.'); 
    if($isValue !== false){ 
     continue; 
    } 

    $key = $arr[$i]; 
    $ret = array('id' => $key , 'num' => ''); 

    $nextIsFloat = strstr($arr[$i+1], ';', TRUE); 
    if(!$nextIsFloat){ 
     $array[] = $ret;   
     continue; 
    }else{ 
     $ret['num'] = $nextIsFloat; 
     $array[] = $ret; 
     $i++;  
    } 
} 
相关问题