2016-02-25 36 views
5

給定一個字符串,例如:PHP獲得字符串中的每個第一個字符的位置到一個數組

$string = " this  is a string "; 

什麼是返回一個包含一個號碼,表示其首先將每個字的CSV陣列的最佳方法字符位置是這樣的:

$string = " this  is a string "; 
      ^ ^^^
      2  11 16 20 

理想情況下,輸出將只是一個數組:

2,11,16,20 

到目前爲止,這裏是我的,但我認爲這是一個有點超過我的頭給我有限的技能:

$string = " this  is a string "; 
$string = rtrim($string); //just trim the right sides spaces 
$len = strlen($string); 
$is_prev_white = true; 
$result = ""; 
for($i = 0; $i <= $len; $i++) { 
    $char = substr($string,$i,1); 
    if(!preg_match("/\s/", $char) AND $prev_white){ 
     $result .= $i.","; 
     $prev_white = false; 
    }else{ 
     $prev_white = true; 
    } 
} 
echo $result; 

我越來越: 2,4,11,16,20,22,24, 26

回答

1

簡單,但進步 :)解決方案與preg_match_allarray_walk功能:使用 preg_match_all功能PREG_OFFSET_CAPTURE flag:

PREG_OFFSET_CAPTURE:如果傳遞此標誌,則對於每次發生的匹配,附屬字符串偏移量也將被返回。注意這改變的匹配值存入一個陣列,其中每個元素是由匹配的字符串的數組在偏移0和它的字符串偏移量受試者在偏移1

$string = " this  is a string "; // subject 
preg_match_all("/\b\w+\b/iu", $string, $matches, PREG_OFFSET_CAPTURE); 

array_walk($matches[0], function(&$v){ // filter string offsets 
    $v = $v[1]; 
}); 
var_dump($matches[0]); 

// the output: 
array (size=4) 
    0 => int 2 
    1 => int 11 
    2 => int 16 
    3 => int 20 

http://php.net/manual/en/function.preg-match-all.php

http://php.net/manual/en/function.array-walk.php

+0

這似乎是正確的答案,但我無法讓他們進入我想要的格式'2,11,16,20'。如圖所示,到達csv列表的最簡單方法是什麼? –

+0

@TripleC,將字符串偏移量轉換爲csv字符串的最簡單方法是使用implode函數:var_dump(implode(「,」,$ matches [0]));'給出'string'2, 11,16,20'' – RomanPerekhrest

+0

我還有一個問題。我的一些單詞中有一些符號,例如'ca#t'我怎樣才能修正這個正則表達式,以便在它們中包含帶有符號的單詞? –

0

您正在尋找的模式非常簡單,以至於不需要正則表達式來匹配它。您可以通過循環字符串來完成此操作。

$l = strlen($string); 
$result = array(); 

// use this flag to keep track of whether the previous character was NOT a space 
$c = false; 

for ($i=0; $i < $l; $i++) { 
    // if the previous character was a space and the current one isn't... 
    if (!$c && $string[$i] != ' ') { 
     // add current index to result 
     $result[] = $i; 
    } 
    // set the 'not a space' flag for the current character 
    $c = $string[$i] != ' '; 
} 
1

Php正則表達式匹配提供了一個標誌來返回te偏移量而不是匹配的子字符串。使用下面的代碼片段:

$hits = []; 
preg_match_all("/(?<=\s)\w/", " this  is a string ", $hits, PREG_PATTERN_ORDER | PREG_OFFSET_CAPTURE); 
$result = array_column ($hits[0], 1); 
$s_result = join (", ", $result); 
echo $s_result; 

的正則表達式模式採用積極的回顧後發現一個空白字符之後的第一個字符。對array_column的調用從作爲模式匹配描述返回的多維數組中提取結果數據。 join將數組元素連接成一個字符串,所選分隔符將其轉換爲一個csv行。

有關更多詳細信息,請參閱array_columnpreg_match_all的php文檔。

現場示例here。根據這個網站,該解決方案從php 5.5.0開始運作。

+0

在字符串以單詞開頭而不是空格的情況下,這項工作是否可行? –

+0

@ Don'tPanic部分地,它不會找到第一個匹配項。不幸的是,lookbehínd參數必須是固定的長度,sio經典變換'(^ | \ s)'不起作用。 Thx的提示。 – collapsar

1

你想要的PREG_OFFSET_CAPTURE標誌:

$string = " this  is a string "; 
preg_match_all('/(?:^|\s)([^\s])/', $string, $matches, PREG_OFFSET_CAPTURE); 

$result = $matches[1]; 

echo var_dump($result); 

的正則表達式是:

(?:^|\s) // Matches white space or the start of the string (non capturing group) 
(^\s) // Matches anything *but* white space (capturing group) 

傳遞PREG_OFFSET_CAPTURE做的preg_match()或preg_match_all()的返回作爲同時含有匹配的兩個元素的數組匹配搜索字符串中的字符串和匹配索引。上面的代碼的結果是:

array(4) { 
    [0]=> array(2) { [0]=> string(1) "t" [1]=> int(2) } 
    [1]=> array(2) { [0]=> string(1) "i" [1]=> int(11) } 
    [2]=> array(2) { [0]=> string(1) "a" [1]=> int(16) } 
    [3]=> array(2) { [0]=> string(1) "s" [1]=> int(20) } 
} 

所以,你可以得到的只是索引的陣列

$firstChars = array_column($result, 1); 
+0

在字符串以單詞開頭而不是空格的情況下,此工作是否可行? –

+0

@ Don'tPanic好點!我相應地更新了正則表達式。 – AmericanUmlaut

0

也可以使用preg_split有兩個標誌。

$string = " this  is a string "; 

$flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE; 

// \W+ matches one or more non word characters 
$csv = implode(",", array_column(preg_split('/\W+/', $string, -1, $flags), 1)); 

echo $csv;

2,11,16,20

如果您需要抵消的話,只是刪除array_columnimplode一部分。

$res = preg_split('/\W+/', $string, -1, $flags);

0

讓我們試試這個沒有正則表達式。我希望這對你有用。

$str=" w this  is a string "; 
echo "<pre>"; 
print_r(first_letter_index($str)); 

function first_letter_index($str) 
{ 
    $arr2 = array_map('trim',str_split($str)); 
    $result=array(); 
    foreach($arr2 as $k=>$v) 
    { 
     if(!empty($v) && empty($arr2[$k-1])) 
     { 
      $result[$k]=$v; 
     } 
    } 
    return $result; 
} 
相關問題