2016-02-25 89 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; 
} 
相关问题