2012-09-23 43 views
5

Ví dụ đầu vào chuỗi: test:)test:)test:) :) test:p test
Wanted chuỗi đầu ra: test :) test :) test :) :) test :p testLàm cách nào để thêm khoảng trống xung quanh chuỗi con nếu các khoảng trống chưa có?

Như bạn có thể thấy trong ví dụ trên, tôi muốn phân tích chuỗi và tạo ra một chuỗi đầu ra với không gian xung quanh thêm tất cả các mã mặt cười được xác định trước.

Tôi đã cố gắng làm điều này với một vài vòng nhưng cuối cùng nó đã không hoạt động 100% như mong đợi và nó là khủng khiếp chậm trên các tài liệu lớn.

Vì vậy, tôi tự hỏi điều gì sẽ là cách tốt nhất và hiệu quả nhất để thực hiện loại phân tích cú pháp này với PHP?

+5

biểu thức thông thường. tìm hiểu chúng, thưởng thức chúng và tìm ra rằng nó thực sự dễ dàng để làm điều đó trong một dòng của 'preg_replace' – Prinzhorn

+0

Tôi đã thử làm điều này với preg_replace() trước đây nhưng nó không hoạt động vì một lý do nào đó. Bạn có thể giúp tôi ở đây không? – Erik

+0

@Prinzhorn Tôi đã thử với '$ text = preg_replace ('/([^]): \\) ([^])/i ',' $ 1 :) $ 2 ', $ text)' nhưng không hoạt động. Bất kỳ ý tưởng có gì sai với nó? – Erik

Trả lời

0

Biểu thức chính quy thay vào đó bạn có thể sử dụng chức năng str_replace. PHP chức năng str_replace có thể nhận mảng làm tham số, vì vậy bạn có thể thử này:

$input = 'test:)test:)test:) :) test:p test'; 
$smileys = array(':)', ':p'); 
$smileys_with_spaces = array(' :)', ' :p'); 
$output = str_replace($smileys_with_spaces, $smileys, $input); // test:) :) -> test:):) 
$output = str_replace($smileys, $smileys_with_spaces, $input); // test:):) -> test :) :) 
+0

Điều này không giống như một giải pháp có thể sử dụng bởi vì nó sẽ thêm không gian quá mức. Nó sẽ, ví dụ, thêm không gian để mã cười đã có không gian arround chúng. – Erik

+0

Cụm từ thông dụng là cách tốt hơn. @xdazz đưa ra giải pháp phù hợp hơn. – doktorgradus

+0

Chỉ cần xóa không gian dư thừa bằng 'str_replace ('', '', $ đầu vào);'. – doktorgradus

0

Hãy thử:

$str = "test:)test:)test:) :) test:p test"; 
$str = preg_replace('/(?<=[a-z])(?=[^a-z\s])|(?<=[^a-z]{2})(?=[a-z])/', ' ', $str); 
+0

Cái này sẽ không hoạt động khi hai nụ cười nằm cạnh nhau. Vì vậy, với $ str được ":) :)", nó không thêm bất kỳ không gian – Erik

+0

@Erik Bạn có mẫu cố định không? – xdazz

0

Update với sự hỗ trợ cho N mặt cười

$smile = array(':)', ':p'); 

//Escape smiley chars for use in rx 
foreach($smile as &$s) { 
    $s = preg_quote($s, '/'); 
}unset($s); 

$rx = implode('|', $smile); 

$str = 'test:)test:)test:) :) test:p test'; 

$str = preg_replace('/ *('.$rx.') */', ' $1 ', $str); 
$str = preg_replace('/('.$rx.') +/', '$1 ', $str); 

echo $str; 
+0

Tác phẩm này hoạt động ngoại trừ việc nó sẽ thêm quá nhiều khoảng trống nếu hai biểu tượng mặt cười nằm cạnh nhau. ví dụ ":) :)" sẽ trở thành " :) :) " khi tôi cần ":) :)" trong ví dụ này. – Erik

+0

bất kỳ ý tưởng nào tôi có thể khắc phục điều đó? – Erik

+0

Bản cập nhật này vẫn sẽ không khắc phục các khoảng trống quá mức ở đầu hoặc cuối chuỗi. Và tôi không thể sử dụng trim() bởi vì nếu bản gốc có dấu cách ở đầu hoặc cuối, thì nó phải theo cách đó. – Erik

2

Nested thay thế:

preg_replace("/\s\s+/", " ", 
    str_replace(Array(":)", ":p"), 
     Array(" :) ", " :p "), $str)); 
0

Nếu bạn cũng muốn không có dấu cách thêm vào lúc bắt đầu/kết thúc, hãy thử này:

$str = ':):)test:)test:)test:) :) test:p:) test'; 
$codes = array(
    ':)', ':p', // Add smileys here. 
); 

// We build the $regexp automatically 
$regexp = array(); 
foreach($codes as $smiley) 
    $regexp[] = preg_quote($smiley, '#'); 
$regexp = implode('|', $regexp); 
// Afterwards, we might replace the above with $regexp = 'VERYCOMPLICATEDSYNTAX'; 

// Split the string at smileys, trimming the smileys as we go, 
// and returning an array of smiley-and-non-smiley parts, except for empty ones 
$parts = preg_split("#\s*($regexp)\s*#", $str, -1, 
    PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE); 

// The new delimiter is a single space. 
$str = implode(' ', $parts); 

Lưu ý rằng tôi đã sử dụng các khớp khoảng trắng \s thay vì một không gian đen; điều này có thể có kết quả không mong muốn nếu bạn có nguồn cấp dữ liệu dòng trong chuỗi gốc. Nếu đúng như vậy, hãy thay thế "\s" bằng dấu cách "".

0

Nên có một giải pháp thanh lịch hơn, nhưng mã dưới đây sẽ làm việc

$patterns = array(); 
$replacements = array(); 

$str = ':) test :)test:) test :)'; 

$smileys = array(':)', ':p'); 

foreach($smileys as &$s) { 
    $s = preg_quote($s, '/'); 
}unset($s); 
$escaped_smiley = implode('|', $smileys); 

$patterns[] = '/([^\s])('.$escaped_smiley.')([^\s])/'; // no spaces 
$patterns[] = '/([\s])('.$escaped_smiley.')([^\s])/'; // space on left 
$patterns[] = '/([^\s])('.$escaped_smiley.')([\s])/'; // space on right 

$patterns[] = '/^('.$escaped_smiley.')([\s])/'; // line starting, space succeding 
$patterns[] = '/^('.$escaped_smiley.')([^\s])/'; // line starting, no space 
$patterns[] = '/([\s])('.$escaped_smiley.')$/'; // line ending, space preceeding 
$patterns[] = '/([^\s])('.$escaped_smiley.')$/'; // line ending, no space 

$replacements[] = '$1 $2 $3'; // no spaces 
$replacements[] = '$1$2 $3'; // space on left 
$replacements[] = '$1 $2$3'; // space on right 

$replacements[] = ' $1$2'; // line starting 
$replacements[] = ' $1 $2'; // line starting 
$replacements[] = '$1$2 '; // line ending 
$replacements[] = '$1 $2 '; // line ending 


$result = preg_replace($patterns, $replacements, $str); 
echo str_replace(' ', '^', $result); 

[Sửa với mã mượn từ @Prinzhorn]

+0

Điều này không thành công chuỗi đầu vào như ':) test:) test:) test :)' – Erik

+0

đầu ra là:) test :) test :) test :) .. chú ý các khoảng trống ở cuối mã biểu tượng cảm xúc đầu tiên và trước cái cuối cùng. – Erik

+0

@Erik chỉnh sửa mã để đưa vào dòng tài khoản bắt đầu và kết thúc. Cũng loại bỏ vòng lặp 'foreach' bằng' implode' và thay thế các biểu tượng mặt cười được trích dẫn bằng cách trích dẫn vòng lặp 'foreach', từ @Prinzhorn. – air4x

0

Nếu bạn chưa giải quyết được vấn đề nêu ra, tôi đã đưa ra với một giải pháp có thể hoạt động. Đầu tiên phát nổ chuỗi ký tự bằng dấu cách làm dấu phân cách, thay thế các biểu tượng mặt cười bằng các khoảng trắng bổ sung và chỉnh sửa chúng bằng implode.

Kiểm tra php fiddle để triển khai.

1
<?php 

$lspace = str_replace(":"," :","test:)test:)test:) :) test:p"); 
$rspace = str_replace(")",") ",$lspace); 
$out = preg_replace("/\s\s+/"," ",$rspace); 


echo $out; 
?> 

đầu ra: test :) test :) test :) :) test :p

Các vấn đề liên quan