5

入力文字列の例: 必要test:)test:)test:) :) test:p test
な出力文字列:test :) test :) test :) :) test :p test

上記の例でわかるように、文字列を解析し、事前定義されたすべてのスマイリー コードの周りにスペースが追加された出力文字列を生成したいと考えています。

いくつかのループでこれを実行しようとしましたが、最終的には 100% 期待どおりに動作せず、大きなドキュメントでは非常に遅くなりました。

だから、PHPでこの種の解析を行うための最良かつ最も効率的な方法は何でしょうか?

4

8 に答える 8

2

ネストされた交換:

preg_replace("/\s\s+/", " ", 
    str_replace( Array( ":)", ":p" ),
        Array( " :) ", " :p " ), $str) );
于 2012-09-23T12:01:14.923 に答える
1
<?php

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


echo $out;
?>

出力:test :) test :) test :) :) test :p

于 2012-09-27T07:04:21.007 に答える
0

正規表現の代わりにstr_replace関数を使用できます。PHP関数str_replaceは配列をパラメーターとして受け取ることができるので、これを試すことができます。

$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 :) :)
于 2012-09-23T11:57:14.753 に答える
0

試す:

$str = "test:)test:)test:) :) test:p test";
$str = preg_replace('/(?<=[a-z])(?=[^a-z\s])|(?<=[^a-z]{2})(?=[a-z])/', ' ', $str);
于 2012-09-23T11:59:15.503 に答える
0

Nスマイリーのサポートで更新

$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;
于 2012-09-23T12:01:08.183 に答える
0

より洗練された解決策があるはずですが、以下のコードは機能するはずです

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

[@Prinzhorn から借用したコードで編集]

于 2012-09-23T13:14:13.600 に答える
0

先頭/末尾に余分なスペースを入れたくない場合は、これを試してください。

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

\sリテラルスペースの代わりに空白マッチャーを使用したことに注意してください。元の文字列に改行がある場合、これは望ましくない結果になる可能性があります。その場合は、\s" " をリテラル スペース " " に置き換えます。

于 2012-09-23T13:08:53.537 に答える
0

まだ問題を解決していない場合は、うまくいく可能性のある解決策を思いつきました. 最初に区切り文字としてスペースを使用して文字列を分解し、スマイリーを追加のスペースに置き換え、それらを implode で rejion します。

実装についてはphpフィドルを確認してください。

于 2012-09-26T10:44:11.497 に答える