Сложная проблема.Нужна помощь с заменой регулярного выражения - PullRequest
0 голосов
/ 27 сентября 2010

Я в процессе обновления программы, которая исправляет субтитры.

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

TL; DR;

Я пытаюсь сделать следующую работу:

Я хочу, чтобы все экземпляры:
"! .", "!." и "! . " стали: "!"

, если только за точкой не следует другая точка, в этом случаеЯ хочу, чтобы все экземпляры:
"!..", "! ..", "! . . " и "!. ." стали: "!..."

Я пробовал этот код:

the_str = Regex.Replace(the_str, "\\! \\. [^.]", "\\! [^.]");

, что близко к первой части того, что я хочу сделать, но я не могу сделать так, чтобы символ [^.] строки замены был таким же, как и в исходной строке ... Пожалуйста, помогите!

Меня интересуют реализации на C # и PHP ...

Ответы [ 2 ]

1 голос
/ 27 сентября 2010
$str = preg_replace('/!(?:\s*\.){2,3}/', '!...', $str);
$str = preg_replace('/!\s*\.(?!\s*\.)/', '!', $str);

Это делает работу с PCRE.Возможно, вы могли бы сделать немного магии, чтобы объединить его с одним, но это больше не будет читаемым.Первый PCRE для !..., второй для !.Они довольно просты.

0 голосов
/ 27 сентября 2010

C #

s = Regex.Replace(s, @"!\s?\.\s?(\.?)\s?", "!$1$1$1");

PHP

$s = preg_replace('/!\s?\.\s?(\.?)\s?/', '!$1$1$1', $s);

Первая точка израсходована, но не захвачена; Вы эффективно выбрасываете это. Группа № 1 захватывает вторую точку, если она есть, или пустую строку, если ее нет. В любом случае подключение его к строке замены три раза дает желаемый результат.

Я использовал \s вместо буквальных пробелов, чтобы сделать его более понятным, и добавил квантификатор ?, чтобы сделать пробелы необязательными. Если вам действительно нужно ограничить его реальными пробелами (не символами табуляции, перевода строки и т. Д.), Вы можете заменить их пробелами. Если вы хотите разрешить более одного пробела за раз, вы можете изменить ? на *, где это уместно - например ::

@"!\s*\.\s*(\.?)\s*"

Также обратите внимание на использование дословных строковых литералов C # - противоядия от обратного слешита. ;)

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