Php 如果空格不是';我还没到呢?

Php 如果空格不是';我还没到呢?,php,parsing,spaces,emoticons,Php,Parsing,Spaces,Emoticons,示例输入字符串:test:)test:)test:):)test:p test 需要输出字符串:test:)test:)test:):)test:p test 正如您在上面的示例中所看到的,我希望解析字符串并生成一个输出字符串,在所有预定义的笑脸代码周围添加空格。 我试图通过几个循环来实现这一点,但最终它并没有像预期的那样100%工作,而且在大型文档上速度非常慢 所以我想知道用PHP进行这种解析的最佳和最有效的方法是什么?可以使用str\u replace函数代替正则表达式。 PHP函数str\

示例输入字符串:
test:)test:)test:):)test:p test

需要输出字符串:
test:)test:)test:):)test:p test

正如您在上面的示例中所看到的,我希望解析字符串并生成一个输出字符串,在所有预定义的笑脸代码周围添加空格。

我试图通过几个循环来实现这一点,但最终它并没有像预期的那样100%工作,而且在大型文档上速度非常慢


所以我想知道用PHP进行这种解析的最佳和最有效的方法是什么?

可以使用
str\u replace
函数代替正则表达式。 PHP函数
str\u 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 :) :)
$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);
尝试:

$str=“test:)test:)test:):)test:p test”;

$str=preg_replace('/(?更新,支持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;
嵌套替换:

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

如果您也不希望在开头/结尾有额外的空格,请尝试以下操作:

$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 :) :)
$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
”替换为“”文字空间。

应该有一个更优雅的解决方案,但下面的代码应该可以工作

$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借用的代码编辑]

如果您还没有解决问题,我想出了一个可行的解决方案。首先用空格作为分隔符分解字符串,用额外的空格替换笑脸,然后用内爆重新对齐

检查实施情况。


<?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

正则表达式。学习它们,享受它们,并发现在一行
preg\u replace
中就可以轻松完成这项工作。我以前尝试过使用preg\u replace()来完成这项工作,但由于某些原因,它没有起作用。你能帮我一下吗?@Prinzhorn我试过用“$text=preg_replace(”/([^]):\)([^])/I“,“$1:)$2',$text)”但不起作用。你知道这有什么问题吗?为什么不管怎样都不添加空格,然后用一个空格替换多个空格?这看起来不是一个可用的解决方案,因为它会添加过多的空格。例如,它会给已经有空格环绕的smiley代码添加空格。正则表达式是更好的方法@xdazz给出了更合适的解决方案。只需通过
str_replace(“”,,$input)删除多余的空格即可。这一个有效,但如果两个笑脸代码相邻,则会增加太多空格。例如,在本例中“:)”将变为“:)”而我需要“:)”。知道如何解决这个问题吗?此更新仍然不会解决字符串开头或结尾的空格过多问题。我不能使用trim(),因为如果原始文件的开头或结尾有空格,它必须保持这种状态。示例输入很简单:“:):”。这将在代码的开头和结尾获得一个空格。但是我需要它只在两个笑脸密码之间多留一个空间。当两个笑脸密码相邻时,这个就不起作用了。因此,如果$str为“:)”,则不会添加任何空格。这会使输入字符串(如“:)test:)test:)test:)失败。输出为:)test:)test:)test:)。。请注意第一个表情符号代码末尾和最后一个表情符号代码之前缺少的空格。@Erik编辑代码时考虑了行的开始和结束。还删除了@Prinzhorn中的
foreach
循环和
intlode
,并用quoting
foreach
循环替换了带引号的笑脸。