2014-10-12 85 views
1

我正在使用php合併文本服務器端的rtf格式文件。 我的字段由文件不同部分的一系列波形符號標識。 每個序列是不同的長度。 爲了使用substr_replace來替換合併材質的字段,我需要計算波浪序列的長度。 我能找到的第一個波浪,而無需使用一個問題:PHP需要統計字符串中的序列中的相同字符數

$firsttilde=strpos($filedata,'~',$currentposinfile); 

在哪裏(在此代碼)$filedata是包含文件的內容和$currentposinfile是關於搜索我的起點的字符串。 我的問題是,我找不到一個函數可以計算序列中相同字符的數量。

從第一代字號$filedata那部分我在看這個樣子的(換句話說,一個波浪號的順序):

「~~~~~~~~~~」

我試過strrpos找到最後一個波浪線,但是在$filedata的後面部分找到了包含波浪線的字段。 我想要做的就是計算來自我意識到字符串中位置的波數的數量,但是我找不到任何函數來執行此操作。 雖然必須有一個。

+0

所以第一代字號的位置之間的差異之間的差異從那個點開始的第一個非波浪字符的位置? – Sumurai8 2014-10-12 10:25:59

回答

0

您可以使用preg_match_all結合PREG_OFFSET_CAPTURE標誌。這將保存在匹配變量中找到該字符串的偏移量,從而允許您找到該字符串並且它是偏移量。

$matches = Array(); 
preg_match_all('/~+/', $input, $matches, PREG_OFFSET_CAPTURE); 

foreach($matches[0] as $k => $v) { 
    $length = strlen($v[0]); 
    echo "Found a string \"{$v[0]}\" beginning at {$v[1]} with length {$length}<br>"; 
} 

對於低於

$input = <<<TEXT 
this is 
~~~~~~~~ 

quite something 
~~~~ 
TEXT; 

的示例文本的輸出將是:

Found a string "~~~~~~~~" beginning at 8 with length 8 
Found a string "~~~~" beginning at 34 with length 4 
0

此使用迭代以檢查文本中的字符。 這是preg_match()解決方案的替代方案,它更緊湊。

<?php 

$text = <<<'TEXT' 
abc 
~~~ 
def 
~~~~~~ 
123 
~~~~~~~~~~ 
TEXT; 

//$currentposinfile = 0; 
//$firsttilde = strpos($text,'~',$currentposinfile); 
//$text = substr($text, $firsttilde); 

$sequenceStarted = false; 
$sequenceLength = 0; 

$textLength = strlen($text); 

for ($i = 0; $i <= $textLength; $i++) { 
    $char = $text[$i]; 

    //echo 'Char ' . $char . ' at ' . $i . PHP_EOL; 

    if($char === '~') { 

     // found start of a sequence 
     if($sequenceStarted === false) { 
      $sequenceLength++;  
      $sequenceStarted = true;  
      $sequenceStartPosition = $i; 
     } 

     // it's a char in sequence    
     continue; 
    } 

    // found first char out of sequence 
    if($char !== '~' && $sequenceStarted === true) { 
     $sequenceStarted = false; 
     $sequenceEndPostion = $i - 1; 
     $sequenceLength = $i - $sequenceStartPosition; 

     echo 'Found a sequence of length: ' . $sequenceLength . ' starting at '.$sequenceStartPosition.' ending at ' . $sequenceEndPostion . '.' . PHP_EOL; 

     #break; 

     $sequenceLength = 0; $sequenceEndPostion = 0; 
    } 
} 

結果:

Found a sequence of length: 3 starting at 5 ending at 7. 
Found a sequence of length: 6 starting at 15 ending at 20. 
Found a sequence of length: 10 starting at 28 ending at 37. 

如果你已經有了序列塊,你可以簡單地使用count_chars()

<?php 

$text = 'ABC~~~123'; 

$data = count_chars($text, 1); 

echo 'The string "'. $text .'" contains the char "~" '. $data[126] . ' times.'; 

$數據[126] =使用ASCII代碼126〜

結果:字符串 「ABC ~~~ 123」 包含炭 「〜」 3次。

演示:https://eval.in/204882

0

通過串下面的函數將循環並返回匹配的數組:

function findSequences($str) 
{ 
    $ret = array(); 
    $len = strlen($str); 
    $count = 0; 

    for($i = 0; $i <= $len; $i ++) 
    { 
     $char = @$str[$i] ?: null; 

     if($char == '~') 
     { 
      $count ++; 
     } 
     elseif($count > 0) 
     { 
      // Found end of sequence 
      $ret[] = array(
       'start' => $i - $count, 
       'end' => $i - 1, 
       'len' => $count 
      ); 

      $count = 0; 
     } 
    } 

    return $ret; 
} 

實例:

print_r(findSequences('~ABC~~~123~~')); 

將輸出用的細節陣列找到的匹配項:

Array 
(
    [0] => Array 
     (
      [start] => 0 
      [end] => 0 
      [len] => 1 
     ) 

    [1] => Array 
     (
      [start] => 4 
      [end] => 6 
      [len] => 3 
     ) 

    [2] => Array 
     (
      [start] => 10 
      [end] => 11 
      [len] => 2 
     ) 

) 
0

謝謝大家的回答。
他們鼓勵我嘗試更難找到一個簡單的解決方案。

我想出了這一點: -

$lasttilde=$firsttilde; 
while ($filedata[$lasttilde]=='~') { $lasttilde++; } 

然後在$filedata特定部分代字符數爲$lasttilde$firsttilde

相關問題