2011-11-15 32 views
6

Tôi gặp vấn đề có vẻ đơn giản khi đối mặt với nó nhưng đã đánh bại kỹ năng regex ít ỏi của tôi. Tôi có một chuỗi mà tôi cần phải chuyển đổi thành một mảng và sau đó xử lý các giá trị tương ứng, đủ đơn giản, nhưng định dạng của chuỗi không thể thay đổi được (nó được tạo ở nơi khác) và logic của nó khiến tôi bối rối.Làm thế nào để tách chuỗi thành chuỗi 2D với Regex?

Chuỗi là:

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

Đó là cơ bản một tập hợp các id và giá trị thập phân (trong trường hợp này id 3 == 12.00). Số lượng id có thể thay đổi tại bất kỳ thời điểm nào và giá trị thập phân có thể nằm trong bất kỳ hoặc tất cả các id.

Trong một thế giới lý tưởng tôi sẽ phải các mảng sau:

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

Do bất kỳ của bạn phù thủy regex biết làm thế nào điều này có thể được thực hiện với ít chửi thề hơn tôi đã có thể đạt được?

tôi đã vậy, đến nay đã có thể trích xuất các id sử dụng:

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

và số thập phân sử dụng:

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

nhưng mất mối tương quan giữa id và giá trị.

+1

bạn có thể giải quyết vấn đề này với nổ & strstr của nó tốt hơn so với regex trong nhiệm kỳ của hiệu suất. – shox

Trả lời

3

Ví dụ:

<?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); 

Output:

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

@Gordon: Xong rồi xong. Cám ơn vì sự gợi ý. :) –

+0

Đây là lý do tại sao tôi yêu Stack Overflow - hoạt động hoàn toàn hoàn hảo! Cám ơn bạn rất nhiều! –

+1

@Matthew Chambers: Bạn được chào đón. :) –

1

Nếu bạn đang hạnh phúc với một danh sách của một trong hai ID hoặc NUM, sau đó bạn chỉ có thể kết hợp hai lần làm việc của bạn XES vào một cuộc gọi:

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

này sẽ cung cấp cho bạn một danh sách các mảng kết hợp, với một trong hai id hoặc num bộ, nếu bạn cũng sử dụng cờ PREG_SET_ORDER.

1

Một cái gì đó như thế này? Kỹ năng php của tôi khá yếu nên bạn sẽ phải kiểm tra cách truy cập các nhóm chụp có tên 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]; 
    } 
} 

Cách hoạt động:

" 
\[    # 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) 
" 

Nó cũng sẽ chăm sóc của các giá trị âm.

0

của nó không phải là phương pháp regex nhưng có lẽ nó làm việc cho bạn: (tất nhiên nó có thể được cải thiện)

$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++;  
    } 
} 
Các vấn đề liên quan