Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在Perl中从字符串中删除换行符_Regex_String_Perl - Fatal编程技术网

Regex 在Perl中从字符串中删除换行符

Regex 在Perl中从字符串中删除换行符,regex,string,perl,Regex,String,Perl,我有一个从文本文件中读取的字符串,但在Ubuntu Linux中,我尝试从末尾删除它的换行符 我用了所有的方法。但是对于s/\n |\r/-/(我查看它是否找到了替换任何新行字符串的字符串),它替换了字符串,但在我打印它时仍会转到下一行。此外,当我使用chomp或chop时,字符串被完全删除。我找不到其他解决办法。我如何解决这个问题 use strict; use warnings; use v5.12; use utf8; use encoding "utf-8"; open(MYINPUT

我有一个从文本文件中读取的字符串,但在Ubuntu Linux中,我尝试从末尾删除它的换行符

我用了所有的方法。但是对于
s/\n |\r/-/
(我查看它是否找到了替换任何新行字符串的字符串),它替换了字符串,但在我打印它时仍会转到下一行。此外,当我使用
chomp
chop
时,字符串被完全删除。我找不到其他解决办法。我如何解决这个问题

use strict;
use warnings;
use v5.12;
use utf8;
use encoding "utf-8";

open(MYINPUTFILE, "<:encoding(UTF-8)", "file.txt");

my @strings;
my @fileNames;
my @erroredFileNames;

my $delimiter;
my $extensions;
my $id;
my $surname;
my $name;

while (<MYINPUTFILE>)
{
    my ($line) = $_;
    my ($line2) = $_;
    if ($line !~ /^(((\X|[^\W_ ])+)(.docx)(\n|\r))/g) {
        #chop($line2);
        $line2 =~ s/^\n+//;
        print $line2 . " WRONG FORMAT!\n";
    }
    else {
        #print "INSERTED:".$13."\n";
        my($id) = $13;
        my($name) = $2;
        print $name . "\t" . $id . "\n";
        unshift(@fileNames, $line2);
        unshift(@strings, $line2 =~ /[^\W_]+/g);
    }
}
close(MYINPUTFILE);
使用严格;
使用警告;
使用v5.12;
使用utf8;
使用编码“utf-8”;

打开(MYINPUTFILE,“您可以使用以下方法擦除换行符:

$line =~ s/[\n\r]//g;
但是,当您这样做时,您需要更改
if
语句中的正则表达式以避免查找它们。我也不认为您希望在
if
中有
/g
。您也不应该有
$line2

我也不会做这种事:

print $line2." WRONG FORMAT!\n";
你能行

print "$line2 WRONG FORMAT!\n";

…相反。此外,print接受一个列表,因此您可以使用逗号,而不是串联字符串。

您可以执行以下操作:

=~tr/\n/

但实际上,
chomp
应该能起作用:

while (<filehandle>){
   chomp;
   ...
}
while(){
咀嚼;
...
}

另外,
s/\n |\r/
仅替换第一次出现的
\r
\n
。如果要替换所有出现的值,则需要在
s/\r |\n//g
末尾使用全局修饰符


注意:如果您在windows中包含
\r
,它通常以
\r\n
结尾,因此您需要同时替换这两个部分(例如
s/(?:\r\n |\n)/
),当然是上面的语句(
s/\r\n//g
)使用全局修饰符无论如何都会解决这个问题。

您可能遇到Windows文件结尾的一行导致问题。例如,“foo-bar\n”之类的字符串实际上是“foo-bar\r\n”。在Ubuntu上使用
chomp
时,您将删除其中包含的任何内容,即“\n”。所以,剩下的是“foo-bar\r”

这是一个微妙但非常常见的错误。例如,如果打印“foo bar\r”并添加换行符,则不会注意到错误:

my $var = "foo bar\r\n";
chomp $var;
print "$var\n";  # Remove and put back newline
但是,当您将该字符串与另一个字符串连接时,会覆盖第一个字符串,因为
\r
会将输出句柄移动到字符串的开头。例如:

print "$var: WRONG\n";
它实际上是“foo bar\r:error\n”,但是
\r
之后的文本将导致以下文本在第一部分的顶部换回:

foo bar\r           # \r resets position
 : WRONG\n          # Second line prints and overwrites
当第一行比第二行长时,这一点更加明显。例如,请尝试以下操作:

perl -we 'print "foo bar\rbaz\n"'
您将获得以下输出:

baz bar
解决方案是删除错误的行尾。您可以使用
dos2unix
命令,或者直接在Perl中使用以下命令:

$line =~ s/[\r\n]+$//;
另外,请注意,您的其他代码有点可怕。例如,您认为
$13
包含什么?这是您以前的正则表达式中第13个括号捕获的字符串。我非常确定该值将始终是未定义的,因为您没有13个括号

您声明了两组
$id
$name
。一个在循环外,一个在顶部。这是一种非常糟糕的做法,依我看。只声明所需范围内的变量,而决不要将所有声明都堆在脚本顶部,除非您明确希望它们是文件的全局声明

当它们具有相同的值时,为什么要使用
$line
$line2
?只需使用
$line

说真的,这是怎么回事:

if ($line !~ /^(((\X|[^\W_ ])+)(.docx)(\n|\r))/g) {
这看起来像是试图混淆,没有冒犯。三个嵌套的否定和一堆不必要的括号

首先,因为它是if-else,所以只需交换它并反转正则表达式即可。其次,
[^\W\uz]
双重否定相当令人困惑。为什么不直接使用
[a-Za-z0-9]
?您可以将其拆分,以便于解析:

if ($line =~ /^(.+)(\.docx)\s*$/) {
    my $pre = $1;
    my $ext = $2;

删除Unicode换行符(包括CRLF对)的正确方法是使用v5.10中引入的
\R
regex元字符

强烈反对使用
use encoding
pragma。您应该使用
使用open
pragma,或者在3-arg
open
上的mode参数中使用编码,或者使用
binmode

 use v5.10;                     # minimal Perl version for \R support
 use utf8;                      # source is in UTF-8
 use warnings qw(FATAL utf8);   # encoding errors raise exceptions
 use open qw(:utf8 :std);       # default open mode, `backticks`, and std{in,out,err} are in UTF-8

 while (<>) {
     s/\R\z//;
     ...
 }
使用v5.10;#最低Perl版本以获得\R支持
使用utf8;#源在UTF-8中
使用警告qw(致命utf8);#编码错误引发异常
使用openqw(:utf8:std);#默认的打开模式,`backticks`和std{in,out,err}在UTF-8中
而(){
s/\R\z/;
...
}

[^\W_u33;]
?因此,您正在尝试匹配非
[A-Za-z0-9_33;
,而不是下划线
?这是很多否定,你确定你说的对吗?我自己觉得很困惑。@TLP请不要假装Perl字符类有ASCII定义,因为这在Perl中是非常错误的。你必须使用。@tchrist你在说什么?那
\w
不是equa是的,当然不是。
\w
等于
[\p{字母}\p{Mark}\p{Decimal\u Number}\p{Connector\u标点符号}]
。这是众所周知的。从Unicode v6.0开始,它覆盖了102724个代码点,比您提到的不足63个代码点多了四个数量级。@stackoverflow,前提是
$data=~s/\R//g
可以工作;请注意,我删除了
\z
边界。不确定为什么要删除所有新行。
$/=undef;$data=;data=~s/\R//g;
。?@stackoverflow当然可以。
$variable = join('',split(/\n/,$variable))