Как преобразовать различные введенные пользователем символы перевода строки в <br>с помощью Perl? - PullRequest
4 голосов
/ 19 июня 2010

У меня есть <textarea> для ввода данных пользователем, и, как им предлагается, пользователи свободно добавляют разрывы строк в браузере, и я сохраняю эти данные непосредственно в базе данных.

После отображения этих данных на веб-странице мне нужно надежно преобразовать разрывы строк в теги <br> с учетом \n \r\n и любых других распространенных разрывов строк. последовательности, используемые клиентскими системами.

Каков наилучший способ сделать это в Perl, не делая подстановок регулярных выражений каждый раз? Естественно, я надеюсь на еще одну замечательную рекомендацию модуля CPAN ...:)

Ответы [ 4 ]

9 голосов
/ 19 июня 2010

Здесь нет ничего плохого в использовании регулярных выражений:

s/\r?\n/<br>/g;
4 голосов
/ 19 июня 2010

На самом деле, если вам приходится иметь дело с пользователями Mac, или если все еще есть какой-то странный компьютер, который использует форм-фиды, вам, вероятно, придется использовать что-то вроде этого:

$input =~ s/(\r\n|\n|\r|\f)/<br>/g;
3 голосов
/ 19 июня 2010
#!/usr/bin/perl

use strict; use warnings;

use Socket qw( :crlf );

my $text = "a${CR}b${CRLF}c${LF}";

$text =~ s/$LF|$CR$LF?/<br>/g;

print $text;

В продолжение комментария @ daxim вот модифицированная версия:

#!/usr/bin/perl

use strict; use warnings;
use charnames ':full';

my $text = "a\N{CR}b\N{CR}\N{LF}c\N{LF}";

$text =~ s/\N{LF}|\N{CR}\N{LF}?/<br>/g;

print $text;

В продолжение комментария @ Маркуса приведен надуманный пример:

#!/usr/bin/perl

use strict; use warnings;
use charnames ':full';

my $t = (my $s = "a\012\015\012b\012\012\015\015c");
$s =~ s/\r?\n/<br>/g;

$t =~ s/\N{LF}|\N{CR}\N{LF}?/<br>/g;

print "This is \$s: $s\nThis is \$t:$t\n";

Thisневерный результат возврата каретки и перевода строки (с которым я когда-то сталкивался).

Вот вывод скрипта на Windows с использованием ActiveState Perl:

C:\Temp> t | xxd
0000000: 5468 6973 2069 7320 2473 3a20 613c 6272  This is $s: a<br
0000010: 3e3c 6272 3e62 3c62 723e 3c62 723e 0d0d  ><br>b<br><br>..
0000020: 630d 0a54 6869 7320 6973 2024 743a 613c  c..This is $t:a<
0000030: 6272 3e3c 6272 3e62 3c62 723e 3c62 723e  br><br>b<br><br>
0000040: 3c62 723e 3c62 723e 630d 0a              <br><br>c..

или, как текст:

chis is $s: a<br><br>b<br><br>
This is $t:a<br><br>b<br><br><br><br>c

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

$s =~ s/\N{LF}|\N{CR}\N{LF}?/<br>/g;

Также, для справки, CGI.pm канонизирует окончания строктаким образом:

# Define the CRLF sequence.  I can't use a simple "\r\n" because the meaning
# of "\n" is different on different OS's (sometimes it generates CRLF, sometimes LF
# and sometimes CR).  The most popular VMS web server
# doesn't accept CRLF -- instead it wants a LR.  EBCDIC machines don't
# use ASCII, so \015\012 means something different.  I find this all 
# really annoying.
$EBCDIC = "\t" ne "\011";
if ($OS eq 'VMS') {
  $CRLF = "\n";
} elsif ($EBCDIC) {
  $CRLF= "\r\n";
} else {
  $CRLF = "\015\012";
}
0 голосов
/ 19 июня 2010

По общему принципу, сохранение данных, введенных пользователем, и преобразование EOL в
каждый раз, когда они отображаются, - лучший (даже Right ™) способ сделать это, и радииметь доступ к исходной версии данных и потому, что в какой-то момент вы можете решить, что хотите изменить алгоритм фильтрации.

Но, нет, я лично не буду использовать регулярное выражение в этом случае.Я бы использовал Parse :: BBCode , который предоставляет целый ряд дополнительных функциональных возможностей (т. Е. Полную поддержку BBCode или, по крайней мере, столько, сколько вы решите не отключать) в дополнение к предоставлению разрывов строк без необходимости в пользователяхявно ввести для них разметку.

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