2012-05-04 132 views
4

我已經搜索了PHP手冊,Stackoverflow和一些論壇,但是我很難理解一些PHP邏輯。也許我只是累了,但我真的很感謝任何人的幫助或指導。分離/解析一個PHP字符串分開某些單詞

我有一個PHP字符串,說:

$string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3'; 

最終,我會非常喜歡我的最終輸出是這個樣子,但剛開陣列現在超過罰款:

<h2>cats</h2> 
<ul> 
    <li>cat1</li> 
    <li>cat2</li> 
    <li>cat3</li> 
</ul> 

<h2>dogs</h2> 
<ul> 
    <li>dog1</li> 
    <li>dog2</li> 
</ul> 

<h2>monkey creatures</h2> 
<ul> 
    <li>monkey_creature1</li> 
    <li>monkey_creature2</li> 
    <li>monkey_creature3</li> 
</ul> 

有一個問題,雖然,有時該字符串會稍有不同:

$string = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3'; 

任何方式,這是我在Stackoverflow的第一個問題,並提前感謝所有幫助傢伙!

編輯:我在某些限制下工作,我不能在字符串之前更改任何代碼。我知道在先進的所有的父母('貓','狗','狐猴','猴子的生物(與空間)'

+2

噢噢。這是一個非常好的問題。我認爲它將以爆炸(「」,$ string)開始,但這只是少數幾個步驟中的第一步。做一個俗氣的假設是安全的,就像第一個3個字母對於一個羣體來說永遠是唯一的 –

+0

「猴子生物」並不真正與它的孩子有關。另外,爲什麼你的數據源是這樣格式化的? – jprofitt

+0

@jprofitt我知道...查看我的編輯。 – envysea

回答

4

我設計了一個答案,無論是否有空格「關鍵字」之間,只要第一個關鍵字是不是複數:)

下面是代碼,可隨時檢查出來,它真的很漂亮你可以用文本:)

<? 
$string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3'; 

$current_prefix = ''; 
$potential_prefix_elements = array(); 

$word_mapping = array(); 

foreach(split(" ", $string) as $substring) { 
    if(strlen($current_prefix)) { 
     // Check to see if the current substring, starts with the prefix 
     if(strrpos($substring, $current_prefix) === 0) 
      $word_mapping[$current_prefix . 's'][] = $substring; 
     else 
      $current_prefix = ''; 
    } 

    if(!strlen($current_prefix)) { 
     if(preg_match("/(?P<new_prefix>.+)s$/", $substring, $matches)) { 
      $potential_prefix_elements[] = $matches['new_prefix']; 

      // Add an 's' to make the keys plural 
      $current_prefix = join("_", $potential_prefix_elements); 

      // Initialize an array for the current word mapping 
      $word_mapping[$current_prefix . 's'] = array(); 

      // Clear the potential prefix elements 
      $potential_prefix_elements = array(); 
     } else { 
      $potential_prefix_elements[] = $substring; 
     } 
    } 
} 

print_r($word_mapping); 

做這裏是輸出結果,我把它作爲一個數組給你,所以你可以很容易地構造一個ul/li層次結構:)

Array 
(
    [cats] => Array 
     (
      [0] => cat1 
      [1] => cat2 
      [2] => cat3 
     ) 

    [dogs] => Array 
     (
      [0] => dog1 
      [1] => dog2 
     ) 

    [monkey_creatures] => Array 
     (
      [0] => monkey_creature1 
      [1] => monkey_creature2 
      [2] => monkey_creature3 
     ) 

) 
+1

順便說一句,這段代碼也適用於你的狐猴示例,它是完全動態的,並將基於複數開始構建數組關鍵字,然後檢查每個關於該前綴的單詞。一旦一個單詞打破了與前綴的比較,該腳本開始建立一個新的密鑰 – Bryan

+1

謝謝。超級及時,正是我需要的! – envysea

+0

非常歡迎!感謝您解決一個有趣的問題:D – Bryan

1

你的第二個例子是一個字符串:

<?php 

$parents = array('cats', 'dogs', 'monkey creatures', 'lemurs'); 
$result = array(); 

$dataString = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3'; 
foreach ($parents as $parent) { 
    // Consider group only if it is present in the data string 
    if (strpos($dataString, $parent) !== false) { 
    $result[$parent] = array(); 
    } 
} 
$parts = explode(' ', $dataString); 
foreach (array_keys($result) as $group) { 
    $normalizedGroup = str_replace(' ', '_', $group); 
    foreach ($parts as $part) { 
    if (preg_match("/^$normalizedGroup?\d+$/", $part)) { 
     $result[$group][] = $part; 
    } 
    } 
} 
print_r($result); 

輸出:

Array 
(
    [cats] => Array 
     (
      [0] => cat1 
      [1] => cat2 
      [2] => cat3 
      [3] => cat4 
      [4] => cat5 
      [5] => cats6 
     ) 

    [dogs] => Array 
     (
      [0] => dogs1 
      [1] => dogs2 
     ) 

    [monkey creatures] => Array 
     (
      [0] => monkey_creature1 
     ) 

    [lemurs] => Array 
     (
      [0] => lemur1 
      [1] => lemur2 
      [2] => lemur3 
     ) 

) 
+0

感謝您花時間寫這篇文章 – envysea

1

這裏是我的$ 0.50

<?php 
$parents = array('cats', 'dogs', 'lemurs', 'monkey creatures'); 

// Convert all spaces to underscores in parents 
$cleaned_parents = array(); 
foreach ($parents as $parent) 
{ 
     $cleaned_parents[] = str_replace(' ', '_', $parent); 
} 

$input = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3'; 

// Change all parents to the "cleaned" versions with underscores 
$input = str_replace($parents, $cleaned_parents, $input); 

// Make an array of all tokens in the input string 
$tokens = explode(' ', $input); 
$result = array(); 

// Loop through all the tokens 
$currentParent = null; // Keep track of current parent 
foreach ($tokens as $token) 
{ 
    // Is this a parent? 
    if (in_array($token, $cleaned_parents)) 
    { 
     // Create the parent in the $result array 
     $currentParent = $token; 
     $result[$currentParent] = array(); 
    } 
    elseif ($currentParent != null) 
    { 
     // Add as child to the current parent 
     $result[$currentParent][] = $token; 
    } 
} 

print_r($result); 

輸出:

Array 
(
    [cats] => Array 
     (
      [0] => cat1 
      [1] => cat2 
      [2] => cat3 
     ) 

    [dogs] => Array 
     (
      [0] => dog1 
      [1] => dog2 
     ) 

    [monkey_creatures] => Array 
     (
      [0] => monkey_creature1 
      [1] => monkey_creature2 
      [2] => monkey_creature3 
     ) 

) 
2

您可能需要使用preg_match_all函數並使用正則表達式。這樣一來,您不必使用任何循環:

$matches = array(); 
$string = 'cats cat1 cat2 cat3 dogs dog1 dog2 monkey creatures monkey_creature1 monkey_creature2 monkey_creature3' 
preg_match_all('/((?:[a-z]+)*?[a-z]+s) ((?:[a-z_]+[0-9] ?)+)*/i', $string, $matches); 

// $matches now contains multidemensional array with 3 elements, indices 
// 1 and 2 contain the animal name and list of those animals, respectively 
$animals = array_combine($matches[1], $matches[2]); 
$animals = array_map(function($value) { 
    return explode(' ', trim($value)); 
}, $animals); 
print_r($animals); 

輸出:

Array 
(
    [cats] => Array 
     (
      [0] => cat1 
      [1] => cat2 
      [2] => cat3 
     ) 

    [dogs] => Array 
     (
      [0] => dog1 
      [1] => dog2 
     ) 

    [monkey creatures] => Array 
     (
      [0] => monkey_creature1 
      [1] => monkey_creature2 
      [2] => monkey_creature3 
     ) 

) 
1

想我將無法提交最佳答案,讓決定爲線最少運行。 (開玩笑,對於非常髒的代碼感到抱歉)

$string = 'cats cat1 cat2 cat3 cat4 cat5 cats6 dogs dogs1 dogs2 monkey creatures monkey_creature1 lemurs lemur1 lemur2 lemur3'; 
$categories = array('cats', 'dogs', 'monkey creatures', 'lemurs'); 

for($i=0; $i<count($categories); $i++) $parts[] = @explode(' ', strstr($string, $categories[$i])); 
for($i=0; $i<count($parts); $i++) $groups[] = ($i<count($parts)-1) ? array_diff($parts[$i], $parts[$i+1]) : $parts[$i]; 
for($i=0; $i<count($groups); $i++) for($j=0; $j<count($groups[$i]); $j++) if(! is_numeric(substr($groups[$i][$j], -1))) unset($groups[$i][$j]); 

print_r($groups); 

您可能會注意到我的方法取決於元素應該有數字後綴的事實。這實際上是無稽之談,但是我們正在處理的輸入也是如此。

我的輸出是:

Array 
(
    [0] => Array 
     (
      [1] => cat1 
      [2] => cat2 
      [3] => cat3 
      [4] => cat4 
      [5] => cat5 
      [6] => cats6 
     ) 

    [1] => Array 
     (
      [1] => dogs1 
      [2] => dogs2 
     ) 

    [2] => Array 
     (
      [2] => monkey_creature1 
     ) 

    [3] => Array 
     (
      [1] => lemur1 
      [2] => lemur2 
      [3] => lemur3 
     ) 

)