2012-02-13 60 views
2

的位置。假設我有以下字符串:分割字符串,請記住分裂

I have | been very busy lately and need to go | to bed early 

通過分割上「|」,您將獲得:

$arr = array(
    [0] => I have 
    [1] => been very busy lately and need to go 
    [2] => to bed early 
) 

第一分割是後2個字,然後是第二個分裂的8個單詞。存儲多少個單詞之後的位置將被存儲:array(2,8,3)。然後,該字符串崩盤傳遞到自定義字符串惡搞:

tag_string('I have been very busy lately and need to go to bed early'); 

我不知道爲tag_string的輸出將是究竟是什麼,除了總的話將保持不變。輸出示例如下:

I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p 
I-ee have been-vb very busy-df lately-nn and need-f to go to bed-uu early-yy 

這會延長字符串中未知數量的字符。我無法控制tag_string。我所知道的是(1)單詞的數量將與之前相同,(2)數組在2之後分開,然後在8個單詞之後分開。我現在需要一個解決方案引爆標記串入同一陣列爲前:

$string = "I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p" 
function split_string_again() { 
    // split after 2nd, and thereafter after 8th word 
} 

隨着輸出:

$arr = array(
    [0] => I have-nn 
    [1] => been-vb very-vb busy lately and-rr need to-r go 
    [2] => to bed early-p 
) 

所以要清楚(我是不是之前):我不能記住拆分strpos,因爲strtring在字符串前後經過tagger,是不一樣的。我需要計算單詞的數量。我希望我已經讓自己更清楚了:)

+0

你可以爆炸它,然後'strlen'數組的每個部分 – seanbreeden 2012-02-13 17:04:32

+0

我會對你想要做的事情感興趣,如果它更高級的話你可能會對[Rope數據結構]感興趣http://en.wikipedia.org/wiki/Rope_%28computer_science%29) - 雖然在PHP中實現它可能會「慢」。 – tplaner 2012-02-13 17:16:07

+0

@evolve我想我現在更好地解釋它 - 請參閱OP的編輯。 – Pr0no 2012-02-14 00:05:09

回答

1

有趣的問題,雖然我覺得rope data structure仍然適用,它可能是一個有點矯枉過正,因爲字詞位置不會改變。這是我的解決方案:

$str = "I have | been very busy lately and need to go | to bed early"; 

function get_breaks($str) 
{ 
    $breaks = array(); 
    $arr = explode("|", $str); 

    foreach($arr as $val) 
    { 
     $breaks[] = str_word_count($val); 
    } 

    return $breaks; 
} 

$breaks = get_breaks($str); 

echo "<pre>" . print_r($breaks, 1) . "</pre>"; 

$str = str_replace("|", "", $str); 

function rebreak($str, $breaks) 
{ 
    $return = array(); 
    $old_break = 0; 

    $arr = str_word_count($str, 1); 

    foreach($breaks as $break) 
    { 
     $return[] = implode(" ", array_slice($arr, $old_break, $break)); 

     $old_break += $break; 
    } 

    return $return; 
} 

echo "<pre>" . print_r(rebreak($str, $breaks), 1) . "</pre>"; 

echo "<pre>" . print_r(rebreak("I have-nn been-vb very-vb busy lately and-rr need to-r go to bed early-p", $breaks), 1) . "</pre>"; 

讓我知道如果您有任何問題,但它是非常自我解釋。有絕對的方法來改善這一點。

+1

謝謝!感謝您的幫助。有一個小小的疏忽,很容易解決:$ old_break = $ break;必須是$ old_break + = $ break;我查看了繩索數據結構,但它確實看起來過於誇張,因爲只有這個特定的操作需要完成。 – Pr0no 2012-02-14 13:08:29

+0

@Reveller好抓!固定。 – tplaner 2012-02-14 14:28:19

3

你不想計算單詞的數量,你想要計算字符串的長度(strlen)。如果它是沒有管道的同一個字符串,那麼你想在一定量之後用substr分割它。

$strCounts = array(); 

foreach ($arr as $item) { 
    $strCounts[] = strlen($item); 
} 

// Later on. 
$arr = array(); 
$i = 0; 
foreach ($strCounts as $count) { 
    $arr[] = substr($string, $i, $count); 
    $i += $count; // increment the start position by the length 
} 

我沒有測試過這個,只是一個「理論」,可能有一些糾結的工作。可能有更好的方法去做,我只是不知道。

+2

對於'strlen'對字數的+1。我認爲這個問題似乎比實際的解決方案更爲複雜。 – rdlowrey 2012-02-13 17:15:29

+0

strlen不是一個解決方案(但它看起來像是因爲我不清楚我的問題)。請參閱編輯的OP。 – Pr0no 2012-02-13 22:21:00

+1

如果我有一段時間後我會看看它:) – 2012-02-13 22:25:08

1

我不太確定我是否理解你真正想達到的目標。但是有幾件事可能對你有幫助:

str_word_count()計算字符串中的字數。 preg_match_all('/\p{L}[\p{L}\p{Mn}\p{Pd}\x{2019}]*/u', $string, $foo);幾乎相同,但在UTF-8字符串上。

strpos()找到在另一個字符串中首次出現的字符串。您可以輕鬆找到所有|的位置與此:

$pos = -1; 
$positions = array(); 
while (($pos = strpos($string, '|', $pos + 1)) !== false) { 
    $positions[] = $pos; 
} 

我仍然不知道我理解你爲什麼不能只使用explode()對於這一點,雖然。

<?php 
$string = 'I have | been very busy lately and need to go | to bed early'; 
$parts = explode('|', $string); 
$words = array(); 
foreach ($parts as $s) { 
    $words[] = str_word_count($s); 
} 
+0

strpos在這裏沒有用(雖然它看起來像它,因爲我不清楚在我的問題)。請參閱更新的OP並告訴我您的想法。 – Pr0no 2012-02-13 22:22:10