2013-07-17 4 views
1

Я пишу regex, чтобы удалить более 1 пробела в строке. Код прост:Замена с s не работает должным образом

my $string = 'A string has more than 1  space'; 
$string = s/\s+/\s/g; 

Но в результате что-то плохое: «Asstringshassmoresthans1sspace». Он заменяет каждое пространство символом 's'.

Существует работа вокруг вместо использования \ s для замены, я использую ''. Таким образом, регулярное выражение становится:

$string = s/\s+/ /g; 

Почему регулярное выражение с \ s не работает?

ответ

6

\s - это только метасимвол в регулярном выражении (и он соответствует не просто пробелу, например табуляторам, символам строки и формы), а не в заменяющей строке. Используйте простое пространство (как вы уже сделали), если вы хотите, чтобы заменить все пробелы на один пробел:

$string = s/\s+/ /g; 

Если вы только хотите, чтобы повлиять на фактические пробелы, используйте

$string = s/ {2,}/ /g; 

(нет необходимости для замены отдельных пространств сами).

1

\s подходит для соответствия любым пробелам. Это эквивалентно следующему:

[\ \t\r\n\f] 

При замене с $string = s/\s+/\s/g;, вы заменяете один или несколько пробельных символов с буквой с. Вот ссылка для ссылки: http://perldoc.perl.org/perlrequick.html

4

Ответ на ваш вопрос: \s - это класс символов, а не буквальный символ. Точно так же, как \w представляет буквенно-цифровые символы, его нельзя использовать для печати буквенно-цифрового символа (кроме w, который он будет печатать, но это не относится к точке).

Что бы я сделал, если бы я хотел, чтобы сохранить тип пробельных символов совпадают, будет:

s/\s\K\s*//g 

\K (держать) последовательность эвакуации будет держать начальный символ пробела от удаления, но все последующие пробелы будут удалены. Если вы не заботитесь о сохранении типа пробелов, решение уже дано Тимом является путь, т.е .:

s/\s+/ /g 
1

Почему не регулярное выражение с \ S работы?

Ваше регулярное выражение с \s действительно работает. Что не работает, это ваша строка замены. И, конечно, как указывали другие, это не должно.

Люди путаются относительно оператора замещения (s/.../.../). Часто я нахожу, что люди считают весь оператор «регулярным выражением». Но это не так, это оператор, который принимает два аргумента (или операнды).

Первый операнд (между первым и вторым разделителем) интерпретируется как регулярное выражение.Второй операнд (между вторым и третьим разделителями) интерпретируется как строка с двумя кавычками (конечно, параметр /e изменяется немного).

Так операция подстановки выглядит следующим образом:

s/REGEX/REPLACEMENT STRING/ 

Регулярное выражение распознает специальные символы, такие как ^ и + и \s. Строка замены - нет.

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

Смежные вопросы