Лучший способ удалить разрывы строк в Perl

Если это c #, см. этот способ, очень просто

string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? 
                   Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();
50
задан Christoffer 20 May 2009 в 08:02
поделиться

4 ответа

Немного покопавшись в документации perlre , я представлю свое лучшее на данный момент предложение, которое, похоже, работает довольно хорошо. В Perl 5.10 класс символов \ R был добавлен как обобщенный перенос строки:

$line =~ s/\R//g;

Это то же самое, что и:

(?>\x0D\x0A?|[\x0A-\x0C\x85\x{2028}\x{2029}])

Я пока оставлю этот вопрос открытым, просто чтобы посмотреть, есть ли еще изящные способы, ожидающие своего предложения.

88
ответ дан 7 November 2019 в 10:41
поделиться

Чтение perlport Я бы предложил что-то вроде

$line =~ s/\015?\012?$//;

, чтобы быть безопасным для любой платформы, на которой вы работаете, и любого стиля перевода строки, который вы можете обрабатывать, потому что что находится в \ r и \ n могут отличаться в зависимости от разновидностей Perl.

7
ответ дан 7 November 2019 в 10:41
поделиться
$line =~ s/[\r\n]+//g;
6
ответ дан 7 November 2019 в 10:41
поделиться

Примечание от 2017 года: File :: Slurp не рекомендуется из-за ошибок проектирования и неуправляемых ошибок. Вместо этого используйте File :: Slurper или Path :: Tiny .

расширение вашего ответа

use File::Slurp ();
my $value = File::Slurp::slurp($filename);
$value =~ s/\R*//g;

File :: Slurp абстрагирует материал ввода-вывода файла и просто возвращает строку для ты.

ПРИМЕЧАНИЕ

  1. Обратите внимание на добавление / g , без него, учитывая многострочную строку, он заменит только первый оскорбительный символ.

  2. Кроме того, удаление $ , которое является избыточным для этой цели, поскольку мы хотим удалить все разрывы строк, а не только разрывы строк перед тем, что подразумевается под ] $ в этой ОС.

  3. В многострочной строке $ соответствует концу строки , и это может вызвать проблемы). Удаляет только последнюю последовательность \ R в файле

  4. / \ R * // : удаляет только первую последовательность \ R в файле
  5. / \ 012? \ 015? // : когда будет удалена только первая последовательность 012 \ 015 , \ 012 или \ 015 , \ 015 \ 012 приведет к отправке либо \ 012 , либо \ 015 .

  6. / \ R * $ // : Если в файле нет байтовых последовательностей '\ 015 $ OSDELIMITER', то разрывы строк NO будут удалены, за исключением символов ОС собственные.

  7. Похоже, никто не понимает, о чем я говорю, поэтому вот пример кода, который протестирован на НЕ удаляет перевод строки. Запустите его, и вы увидите, что перевод строки остается включенным.

    #!/usr/bin/perl 
    
    use strict;
    use warnings;
    
    my $fn = 'TestFile.txt';
    
    my $LF = "\012";
    my $CR = "\015";
    
    my $UnixNL = $LF;
    my $DOSNL  = $CR . $LF;
    my $MacNL  = $CR;
    
    sub generate { 
        my $filename = shift;
        my $lineDelimiter = shift;
    
        open my $fh, '>', $filename;
        for ( 0 .. 10 )
        {
            print $fh "{0}";
            print $fh join "", map { chr( int( rand(26) + 60 ) ) } 0 .. 20;
            print $fh "{1}";
            print $fh $lineDelimiter->();
            print $fh "{2}";
        }
        close $fh;
    }
    
    sub parse { 
        my $filename = shift;
        my $osDelimiter = shift;
        my $message = shift;
        print "Parsing $message File $filename : \n";
    
        local $/ = $osDelimiter;
    
        open my $fh, '<', $filename;
        while ( my $line = <$fh> )
        {
    
            $line =~ s/\R*$//;
            print ">|" . $line . "|<";
    
        }
        print "Done.\n\n";
    }
    
    
    my @all = ( $DOSNL,$MacNL,$UnixNL);
    generate 'Windows.txt' , sub { $DOSNL }; 
    generate 'Mac.txt' , sub { $MacNL };
    generate 'Unix.txt', sub { $UnixNL };
    generate 'Mixed.txt', sub {
        return @all[ int(rand(2)) ];
    };
    
    
    for my $os ( ["$MacNL", "On Mac"], ["$DOSNL", "On Windows"], ["$UnixNL", "On Unix"]){
        for ( qw( Windows Mac Unix Mixed ) ){
            parse $_ . ".txt", @{ $os };
        }
    }
    

    Для CLEARLY необработанного вывода см. Здесь: http://pastebin.com/f2c063d74

    Обратите внимание, что есть определенные комбинации, которые, конечно, работают, но они, вероятно, те, которые вы вы наивно протестировали себя.

    Обратите внимание, что в этом выводе все результаты должны иметь вид > | $ string | <> | $ string | < с NO LINE FEEDS , чтобы быть считается допустимым выходом.

    и $ string имеет общий вид {0} $ data {1} $ delimiter {2} где во всех источниках вывода должно быть либо:

    1. Ничего не найдено между {1} и {2} только
    2. | <> | между {1} и {2}
6
ответ дан 7 November 2019 в 10:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: