php - preg_replace - несопоставленные символы, кроме совпадающих строк

1

У меня есть строки, которые вот так:

// example
$str1 = "     10.503 GB  3.4 GiB   ";
$str2 = "  40.29 KiB    ";
$str3 = "14.3 GB    2.1 51   ";

Вот мое регулярное выражение, которое соответствует строкам "10.503 GB", "3.4 GiB", "40.29 KiB" и "14.3 GB" соответственно

$regex = '/(\d+\.\d+ [A-Za-z]+[^\s])/';
preg_match_all($regex, $str1, $out1);
preg_match_all($regex, $str2, $out2);
preg_match_all($regex, $str3, $out3);

Таким образом, проблема заключается в том, как заменить не совпадающие символы, которые не соответствуют шаблону регулярного выражения с пользовательским символом? Пример ниже:

$char = 'A'; // assume this is user input
$str1 = "     10.503 GB  3.4 GiB   ";
$str2 = "  40.29 KiB    ";
$str3 = "14.3 GB    2.1 51   ";

/* preg_replace (or another preg_* magic here */

поэтому последние строки будут

$str1 = "AAAAA10.503 GBAA3.4 GiBAAA";
$str2 = "AA40.29 KiBAAAA";
$str3 = "14.3 GBAAAAAAAAAAAAA";

Я знаю решения без использования preg_replace, но просто притворяюсь, что preg_replace - это необходимость здесь (или другое preg_ *, если вы предпочитаете)

Так это возможно? и если да, то как я могу это сделать?

  • 1
    Если не PHP, какой движок вы также должны поддерживать? Я думаю, что на этот вопрос ответили. Только Boost может выполнить эту работу правильно с шаблоном условной замены, другие будут давать неточный вывод (с одним дополнительным A после каждого несоответствия). Посмотрите на другую демонстрацию PHP регулярных выражений .
  • 0
    @Casimir et Hippolyte дал прекрасный ответ на мою проблему :) также спасибо стрибижеву за информацию!
Теги:
preg-replace

1 ответ

1
Лучший ответ

Что-то вроде:

~\d+\.\d+ [a-zA-Z]+\b(*SKIP)(*F)|.~

с заменой А.

демонстрация

(*SKIP) заставляет не пытаться повторить ранее согласованные позиции, когда паттерн терпит неудачу. (*F) или (*FAIL) заставляет шаблон терпеть неудачу.

Обратите внимание, что для обработки значений без десятичных знаков вы должны заменить \d+\.\d+ на \d+(?:\.\d+)?


Если вы не используете движок регулярных выражений с этими глаголами управления возвратом (доступно только с Perl, языком, использующим PCRE, или новым модулем регулярного выражения Python), вы можете добиться того же с группой захвата и обратной репликой:

pattern: ((?:\d+(?:\.\d+)? [a-zA-Z]+\b)*).
replacement: \1A
or: $1A

С помощью PCRE, Perl, регулярного выражения Python и Ruby 2 вы также можете сделать это:

pattern: (?:\d+(?:\.\d+)? [a-zA-Z]+\b)*\K.
replacement: A
  • 0
    Вау! Я полностью удивился, когда увидел ( SKIP) и (* FAIL)! но на протяжении всего моего дальнейшего чтения это работает только в механизме PCRE, на который опирается PHP, но как я могу это сделать, не завися от этой функции? (пример использования другого движка регулярных выражений) * извините за задание еще одного вопроса здесь
  • 1
    @MohdShahril: я добавил способ без обратного отслеживания глаголов управления, но имейте в виду, что общий шаблон регулярных выражений не существует, каждый язык может иметь свой собственный механизм регулярных выражений, реализацию и синтаксис.
Показать ещё 5 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню