2011-11-15 13 views
6

मुझे एक समस्या है जो इसके चेहरे पर सरल लगती है लेकिन मेरे कम रेगेक्स कौशल को हरा दिया है। मेरे पास एक स्ट्रिंग है जिसे मुझे एक सरणी में बदलने की आवश्यकता है और उसके बाद मानों को संसाधित करना है, जो कि काफी आसान है, लेकिन स्ट्रिंग का प्रारूप बदला नहीं जा सकता है (यह कहीं और उत्पन्न होता है) और इसके तर्क ने मुझे परेशान किया है।रेगेक्स के साथ स्ट्रिंग को 2 डी सरणी में कैसे विभाजित करें?

स्ट्रिंग है:

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

यह मूल रूप से आईडी और दशमलव मान का एक सेट है (इस मामले में आईडी 3 == 12.00)। किसी भी पल में आईडी की मात्रा बदल सकती है और दशमलव मान किसी भी या सभी आईडी में हो सकते हैं।

मैं निम्नलिखित सरणी के लिए होता है एक आदर्श दुनिया में:

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

आप regex जादूगरों में से किसी को पता है कि यह कैसे कम शपथ ग्रहण के साथ पूरा किया जा सकता की तुलना में मैं प्राप्त कर लिया है है?

मैं अब तक पहचान-पत्र का उपयोग कर निकालने के लिए सक्षम किया गया है: का उपयोग कर दशमलव

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

और:

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

लेकिन आईडी के और मूल्यों के बीच संबंध खो देते हैं।

+1

आप विस्फोट और इसके प्रदर्शन की अवधि में regex की तुलना में बेहतर 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

@ मैथ्यू चेम्बर्स: आपका स्वागत है। :) –

0

php पर एक नज़र आदेश ले लो विस्फोट - http://php.net/manual/en/function.explode.php

+0

ठीक है, अकेले विस्फोट से मदद नहीं मिलती है, क्योंकि फ़ील्ड और कुंजी => मान के बीच डिलीमीटर समान है। – Boldewyn

+0

प्रश्न विकसित हुआ है क्योंकि मैंने अपना जवाब पोस्ट किया है ... – rogerlsmith

1

आप की एक सूची के साथ खुश हैं, तो या तो आईडी या NUMs, तो आप बस अपने दो कामकाजी रिज गठबंधन कर सकते हैं एक कॉल में XES:

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

यह आपको, साहचर्य सरणियों की एक सूची दे देंगे तो id या num सेट के साथ, अगर आप भी 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

इसकी नहीं regex दृष्टिकोण लेकिन शायद यह आप के लिए काम करता है: (निश्चित रूप से यह सुधार किया जा सकता)

$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++;  
    } 
} 
संबंधित मुद्दे