Perl: функція для обрізки пробілів, що ведуть і закінчують рядок


82

Чи існує вбудована функція для обрізки пробілів, що ведуть та відстають, так, що trim(" hello world ") eq "hello world"?


3
FYI: рівність рядків у Perl перевіряється оператором eq.
A. Rex

5
Трохи роз’яснень щодо усіх отриманих відповідей: s/^\s+|\s+$//g;vs s/^\s*//; s/\s*$//;Останнє (колись трохи) більш ідіоматичний спосіб зробити це, оскільки запуск движка регулярних виразів насправді швидший, ніж чергування, у цьому випадку. Детальніше про це ви можете прочитати в «Освоєнні регулярних виразів» Джеффрі Фрідла. (Якщо це не було виправлено в якійсь новішій версії Perl, в цьому випадку хтось, будь ласка, виправте мене!)
Хугмейр

4
Виходячи з фону Java та .NET, я майже вражений, що це не вбудовано в мову! ДЯКУЮ ВСІМ!
Лендон Кун,

3
@ landon9720, це дещо: Scalar :: Util має обробку і є основним з 5.7.3 - Це 2002 рік!
Hugmeir

3
Хугмейр, це неправильно, див. Відповідь Ефіра .
daxim

Відповіді:


89

Ось один із підходів до використання регулярного виразу:

$string =~ s/^\s+|\s+$//g ;     # remove both leading and trailing whitespace

Perl 6 включатиме функцію обрізки:

$string .= trim;

Джерело: Вікіпедія


5
Я дивлюсь це приблизно раз на місяць. Шкода, що я не можу кожного разу проголосувати.
kyle

82

Це є в Струнний :: Util з trimметодом:

Примітка редактора: String::Utilце не основний модуль, але ви можете встановити його з CPAN за допомогою [sudo] cpan String::Util.

use String::Util 'trim';
my $str = "  hello  ";
$str = trim($str);
print "string is now: '$str'\n";

відбитки:

рядок тепер "привіт"

Однак це досить легко зробити самостійно:

$str =~ s/^\s+//;
$str =~ s/\s+$//;

@ mklement0, і це ніколи не буде. Але це не актуально, оскільки всі повинні використовувати модулі від CPAN.
Ефір

2
чому всі повинні використовувати модулі від CPAN? Це ускладнює узгодженість при використанні perl з вашого дистрибутива Linux (debian, redhat, ubuntu) у поєднанні з вручну встановленими модулями CPAN. Набагато краще, якщо щось можна зробити у perl за допомогою модулів, які доступні як пакети для дистрибутива linux
Marki555,

Модулі @ Marki555, доступні як пакети у вашому дистрибутиві Linux, є від CPAN - вони щойно були перепаковані. Як правило, ви можете попросити пакувати певний модуль, якщо цього ще не було зроблено (люди з debian особливо чуйні та корисні).
Ефір

1
Я знаю, що вони також від CPAN ... Так, загалом я можу запитати новий pkg для debian, але це не допоможе мені для мого встановленого стабільного випуску debian ... ось чому я віддаю перевагу модулям пакетів, але використовую безпосередньо CPAN, якщо дійсно потрібні.
Marki555

4
@Ether З усією повагою, я дуже вдячний, знаючи, що це непрофільний модуль. У цій публікації йдеться про використання модуля замість досить простого однорівневого регулярного виразу. Якщо модуль є основним, я був би набагато більш відкритим для нього. Це актуально в даному випадку.
UncleCarl 01.03.18

26

Вбудованої trimфункції немає, але ви можете легко реалізувати власну, використовуючи просту заміну:

sub trim {
    (my $s = $_[0]) =~ s/^\s+|\s+$//g;
    return $s;
}

або з використанням неруйнівного заміщення в Perl 5.14 і пізніших версіях:

sub trim {
   return $_[0] =~ s/^\s+|\s+$//rg;
}



3

Для тих, хто використовує Text :: CSV, я знайшов цей потік, а потім помітив у модулі CSV, що його можна вилучити за допомогою перемикача:

$csv = Text::CSV->new({allow_whitespace => 1});

Логіка полягає в тому, що якщо ви хочете позбавитись, то ви встановлюєте на 1. Перейдіть на малюнок. Сподіваюся, це комусь допоможе.




2

Я також використовую позитивний лукахед для обрізки повторюваних пробілів усередині тексту:

s/^\s+|\s(?=\s)|\s+$//g

-4

Ні, але ви можете використовувати s///оператор заміни та \sтвердження пробілу, щоб отримати однаковий результат.


Це видалить пробіли між словами, а не лише в кожному кінці рядка.
DarenW

@DarenW: залежить від способу використання.
Філіп Поттер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.