Мне нужен Php-RegEx, чтобы найти все двойные пробелы между ключевым словом start и end и удалить их.

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

Может кто-нибудь мне помочь ?

1
Integer 27 Фев 2016 в 16:14

4 ответа

Лучший ответ

Вы можете сделать это с помощью такого шаблона, используя якорь \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

демо

2
Casimir et Hippolyte 27 Фев 2016 в 15:04

Если вы хотите, чтобы регулярное выражение заменяло все пробелы, включая табуляции и пустые строки, вы можете использовать это:

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

Он заменит TAB и новую строку, даже если это только один, между символами. Множественные (любые) пробелы также будут сокращены до одного символа пробела.

Здесь есть регулярное выражение только для нескольких пробелов (но в этом случае быстрее использовать str_replace, как в другом ответе здесь)

$s = preg_replace('/  */', ' ', $s);
-1
micropro.cz 27 Фев 2016 в 13:26

Я плохо разбираюсь в php, поэтому я дам решение независимо от языка. Это будет полезно, поскольку вы можете выбрать свой язык и реализовать его аналогичным образом.

Итак, решение. Что ж, не существует простого способа найти double space между двумя keywords. Может быть какое-то элитное регулярное выражение. Но мой подход довольно прост.

Шаг 1: Найдите текст между keywords, полученный с помощью (?<=:keyword_start:).*?(?=:keyword_end:).

Regex101 Demo здесь.

Шаг 2: Замените double spaces или multiple tabs в найденном тексте простым \s+.

Regex101 Demo здесь.

0
user2705585user2705585 27 Фев 2016 в 13:58

Вы можете использовать обратный вызов, чтобы узнать, что находится между словами.

$str = preg_replace_callback('/:keyword_start:(.*?):keyword_end:/s', function ($m) {
  return ':keyword_start:' . preg_replace('/\s{2,}/', " ", $m[1]) . ':keyword_end:';
}, $str);
  • (.*?) между токенами захватывает lazy любое количество любых символов для $1
  • \s{2,} соответствует двум или более пробелам.
  • s флаг после закрывающего разделителя заставляет точку соответствовать символам новой строки

Посмотреть демо на eval.in


Это можно сделать с помощью одного изящного регулярного выражения, но более подвержено ошибкам и объяснение занимает больше времени. Что-то типа

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

Демо на regex101

1
bobble bubble 27 Фев 2016 в 14:40