2016-02-25 17 views
5

Cho một chuỗi, ví dụ:PHP có được vị trí của mỗi ký tự đầu tiên trong một chuỗi thành một mảng

$string = " this  is a string "; 

phương pháp tốt nhất để trả lại một mảng csv chứa một số cho mỗi từ mà đại diện đầu tiên của mình là gì nhân vật vị trí như thế này:

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

Lý tưởng nhất là đầu ra sẽ chỉ là một mảng:

2,11,16,20 

Cho đến nay, đây là những gì tôi có nhưng tôi nghĩ rằng đây là một chút trên đầu của tôi cho kỹ năng hạn chế của tôi:

$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; 

Tôi nhận: 2,4,11,16,20,22,24, 26

Trả lời

1

đơn giản, nhưng tiến :) giải pháp với preg_match_allarray_walk chức năng: Sử dụng preg_match_all chức năng với PREG_OFFSET_CAPTURE cờ:

PREG_OFFSET_CAPTURE: Nếu lá cờ này được thông qua, đối với mỗi trận đấu xảy ra, bù trừ chuỗi ứng dụng cũng sẽ được trả lại.Lưu ý rằng điều này thay đổi giá trị của trận vào một mảng mà mỗi phần tử là một mảng gồm các chuỗi xuất hiện tại offset 0 và chuỗi của nó bù đắp vào đề tại offset 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

Điều này có vẻ là câu trả lời đúng nhưng tôi không thể đưa chúng vào định dạng '2,11,16,20' mà tôi đang cố gắng. Cách dễ nhất để đến danh sách csv như được hiển thị là gì? –

+0

@TripleC, cách dễ nhất để có được những mảng với chuỗi offsets thành chuỗi csv là sử dụng hàm 'implode':' var_dump (implode (",", $ matches [0])); 'cho' string '2, 11,16,20'' – RomanPerekhrest

+0

Tôi có một câu hỏi khác. Một vài từ của tôi có biểu tượng bên trong chúng như, ví dụ, 'ca # t' Làm thế nào tôi có thể sửa regex này để bao gồm các từ có ký hiệu trong đó? –

0

Mẫu mà bạn đang tìm kiếm đơn giản, đủ để regex không cần thiết. Bạn có thể làm điều này bằng cách chỉ lặp qua chuỗi.

$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

Kết hợp regex Php cung cấp cờ để trả lại bù trừ te thay vì các phần tử phù hợp. Sử dụng đoạn mã sau:

$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; 

Mẫu regex sử dụng giao diện tích cực để tìm char đầu tiên sau ký tự khoảng trắng. Cuộc gọi đến array_column trích xuất dữ liệu kết quả từ mảng đa chiều được trả về dưới dạng mô tả đối sánh mẫu. join ghép các phần tử mảng thành một chuỗi, dấu tách được chọn biến nó thành một dòng csv.

Để biết thêm chi tiết, hãy tham khảo tài liệu php cho array_columnpreg_match_all.

Ví dụ trực tiếp here. Theo trang web này, giải pháp hoạt động như của php 5.5.0.

+0

Điều này có hoạt động trong trường hợp chuỗi bắt đầu bằng một từ thay vì khoảng trắng không? –

+0

@ Don'tPanic Một phần, nó sẽ không tìm thấy sự xuất hiện đầu tiên. Thật không may, đối số lookbehínd phải có độ dài cố định, sio phép luân phiên kinh điển '(^ | \ s)' sẽ không hoạt động. Thx cho gợi ý. – collapsar

1

Bạn muốn cờ 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); 

Các regex là:

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

Đi qua PREG_OFFSET_CAPTURE làm preg_match() hoặc preg_match_all() trả lại phù hợp như mảng hai phần tử có chứa cả phù hợp chuỗi và chỉ mục của đối sánh đó bên trong chuỗi được tìm kiếm. Kết quả của đoạn mã trên là:

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) } 
} 

Vì vậy, bạn có thể nhận được các mảng chỉ các chỉ số với

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

Thao tác này có hoạt động trong trường hợp chuỗi bắt đầu bằng một từ thay vì dấu cách không? –

+0

@ Don'tPanic Điểm tốt! Tôi đã cập nhật regex cho phù hợp. – AmericanUmlaut

0

Bạn cũng có thể sử dụng preg_split với hai cờ.

$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

Nếu bạn cần những lời có bù đắp, chỉ cần loại bỏ các phần array_columnimplode.

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

0

Hãy thử điều này mà không cần regex. Tôi hy vọng nó làm việc cho bạn.

$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; 
} 
Các vấn đề liên quan