PHP 正则表达式删除两个单词之间的双空格

PHP RegEx to remove double spaces between 2 words

我需要 Php-RegEx 来查找开始关键字和结束关键字之间的所有双空格并将其删除。

$teststring = 'This is a teststring ... :keyword_start: this is    the content    with double spaces :keyword_end: more text ... :keyword_start: this is the second   content    with double spaces :keyword_end: ... more text';

我需要以下结果:

This is a teststring ... :keyword_start: this is the content with double spaces :keyword_end: more text ... :keyword_start: this is the second content with double spaces :keyword_end: ... more text

这是我试过的:(但它不起作用)

$teststring = preg_replace('#(:keyword_start:)\s\s+(:keyword_end:)#si', '', $teststring);

谁能帮帮我?

如果你想让正则表达式替换所有白色space,包括制表符和空行,你可以使用这个:

$s = preg_replace('/\s+/', ' ', $s);

它会在字符之间替换 TAB 和换行符,即使它只有一个。多个(任何)白色space也会减少到一个space字符。

仅用于多个 space 的正则表达式在这里(但在这种情况下使用 str_replace 更快,就像在此处的另一个答案中一样)

$s = preg_replace('/  */', ' ', $s);

嗯,我不擅长php,所以我会不分语言给出解决方案。这将很有帮助,因为您可以选择您的语言并以同样的方式实施它。

于是解决。好吧,没有一种简单的方法可以在两个 keywords 之间找到 double space。可能有一些 elite 正则表达式。但我的方法非常简单。

第一步:查找keywords之间的文本,使用(?<=:keyword_start:).*?(?=:keyword_end:)实现。

Regex101 Demo here.

步骤 2: 使用简单的 \s+.

替换找到的文本中的 double spacesmultiple tabs

Regex101 Demo here.

您可以使用 \G 锚点使用这种模式来完成。此锚点匹配上一个匹配项之后的位置(默认情况下是字符串的开头)。有了它你可以获得连续的匹配(直到你打破连续性):

$pattern = '~(?:\G(?!\A)|:keyword_start:\s)(?:(?!:keyword_end:)\S+\s)*+\K\s+~S';

$result = preg_replace($pattern, '', $str);

图案详情:

~             # pattern delimiter
(?:           # non-capturing group
    \G(?!\A)             # contiguous branch (not at the start of the string)
  |                      # OR
    :keyword_start:\s    # start branch
)
(?:
    (?!:keyword_end:)\S+ # all non-blank characters that are not the "end word"
    \s                   # a single space
)*+                   # repeat the group until a double space or the "end word"
\K                    # remove all on the left from the match result
\s+                   # spaces to remove
~S      # "STUDY" modifier to improve non anchored patterns

demo

您可以在单词之间使用 callback

$str = preg_replace_callback('/:keyword_start:(.*?):keyword_end:/s', function ($m) {
  return ':keyword_start:' . preg_replace('/\s{2,}/', " ", $m[1]) . ':keyword_end:';
}, $str);
  • (.*?) 令牌之间 captures lazily 任意数量的任意字符到 </code></li> <li><code>\s{2,} 匹配两个或更多 whitespaces
  • s flag 在结束定界符后使点匹配换行符

See demo at eval.in


它可以用一个漂亮的正则表达式来完成,但更容易失败并且解释需要更长的时间。像

/(?::keyword_start:|\G(?!^)\S+)\K(?<!_end:)\s+/

Demo at regex101