2011-10-19 20 views
5

Tôi đã thử tìm kiếm nội dung này ở đây và trên Google, vì vậy nếu tôi bỏ lỡ điều gì đó hiển nhiên, tôi xin lỗi. Có thể tôi chỉ đơn giản là không biết tên cho định dạng của những con số này.PHP: Có cách nào đơn giản để phân tích cú pháp danh sách các số (như một chuỗi, như "1-3,5,7-9") thành một mảng không?

Điều tôi đang tìm kiếm là bắt đầu bằng chuỗi, như "1-3,5,7-9" và biến nó thành mảng PHP với các mục sau: 1,2,3,5 , 7,8,9

Tôi biết cách làm điều này bằng cách sử dụng preg_split trên dấu phẩy, sau đó lặp lại và mở rộng bất kỳ dấu, nhưng tôi cảm thấy như phải có một cách dễ dàng hơn/tốt hơn.

EDIT

Tôi không làm cho rõ ràng, nhưng chuỗi cần bao gồm nhịp! Điều đó có nghĩa là nếu chuỗi của tôi là "1-9", mảng kết quả của tôi phải là "1,2,3,4,5,6,7,8,9" KHÔNG CHỈ là "1,9". Xin lỗi vì điều đó không rõ ràng trước đây.

+1

bạn nhìn phát nổ? http://php.net/manual/en/function.explode.php –

+5

Tôi rất vui khi mọi người ở đây đọc kỹ câu hỏi ... – animuson

+0

Tôi đã chỉnh sửa bài đăng ... vấn đề của tôi là kéo dài, như "1-5 "cần kết quả" 1,2,3,4,5 "không chỉ" 1,5 " – Bing

Trả lời

11

Không hoàn toàn chắc chắn ý bạn là gì bằng cách "mở rộng". Dù sao, đây là cách tôi sẽ làm điều đó với exploderange:

$input = '1-3,5,7-9'; 
$output = array(); 

foreach (explode(',', $input) as $nums) { 
    if (strpos($nums, '-') !== false) { 
     list($from, $to) = explode('-', $nums); 
     $output = array_merge($output, range($from, $to)); 
    } else { 
     $output[] = $nums; 
    } 
} 

Nếu có một cách tốt hơn mà không sử dụng eval (hoặc sửa đổi PCRE e), tôi không biết bất kỳ.

Dưới đây là, cho giải trí của bạn, một lớp lót (mà không may sử dụng eval) trả về kết quả tương tự, nhưng ...

Disclaimer: Sử dụng eval không được khuyến khích trong nhiều trường hợp vì nó có thể tạo ra rủi ro bảo mật và các vấn đề khác. Tôi sẽ không sử dụng nó nhưng vẫn khả thi.

Với những gì đã nói, ở đây nó là:

$output = explode(',', preg_replace('/([0-9]*)-([0-9]*)/e', 'implode(",", range($1, $2));', $input)); 
+0

Điều này làm việc, cảm ơn! – Bing

1

Tôi không biết một đơn giản được xây dựng theo cách, vì nó không phải là cái gì đó là tất cả các chung tôi nghi ngờ có điều gì đó được xây dựng trong.

Cách bạn đang mô tả âm thanh như một cách tiếp cận hợp lý. Có thể làm điều đó chỉ với một lần lặp qua chuỗi, nhưng trừ khi đó là một vấn đề hiệu suất đã biết, tôi sẽ không bận tâm với nó.

+0

+1 Tôi chắc chắn bỏ qua kéo dài và xem chúng dưới dạng dấu phân cách. – Josh

1
$str = '1-3,5,7-9'; 
$arr = explode(',', $str); 
$result = array(); 
foreach($arr as $a){ 
    $x = explode('-', $a); 
    if(count($x) === 2){ 
    $x = range($x[0], $x[1]); 
    } 
    $result = array_merge($result, $x); 
} 
print_r($result); 

Không chắc hiệu quả như thế nào đây là, nhưng nó được công việc làm.

0

Đã đi xa để thực hiện việc này và tôi đã quay lại để xem 2 câu trả lời rồi. :(

<?php 
function arrex($s){ 
    $arr = explode("-", $s); 
    $v=$arr[0] + 1; 
    $val = array(); 
      while($v!=$arr[1]){ 
       $val[$v] = $v; 
        $v++; 
      } 
    array_unshift($val, $arr[0]); 
    array_push($val, $arr[1]); 
return $val; 
} 
$s = "1-9"; 
print_r(arrex($s)); 
?> 

Đầu ra

Array 
(
    [0] => 1 
    [1] => 2 
    [2] => 3 
    [3] => 4 
    [4] => 5 
    [5] => 6 
    [6] => 7 
    [7] => 8 
    [8] => 9 
) 
1

Những thói quen ở trên hoạt động tốt, nhưng có một số thiếu sót:

  1. Spaces trong chuỗi đảo lộn thói quen
  2. trùng lặp không lấy ví dụ5,4-7 cho 5,4,5,6,7
  3. Các số này không được sắp xếp.

Tôi đã thay đổi mã để sắp xếp ra những vấn đề này:

function parsenumbers($input) 
{ 
    /* 
    * This routine parses a string containing sets of numbers such as: 
    * 3 
    * 1,3,5 
    * 2-4 
    * 1-5,7,15-17 
    * spaces are ignored 
    * 
    * routine returns a sorted array containing all the numbers 
    * duplicates are removed - e.g. '5,4-7' returns 4,5,6,7 
    */ 
    $input = str_replace(' ', '', $input); // strip out spaces 
    $output = array(); 
    foreach (explode(',', $input) as $nums) 
    { 
     if (strpos($nums, '-') !== false) 
     { 
      list($from, $to) = explode('-', $nums); 
      $output = array_merge($output, range($from, $to)); 
     } 
     else 
     { 
      $output[] = $nums; 
     } 
    } 

    $output = array_unique($output, SORT_NUMERIC); // remove duplicates 
    sort($output); 

    return $output; 
} 
Các vấn đề liên quan