perl正则表达式删除破折号

时间:2015-01-07 19:16:39

标签: regex perl

我正在处理一些文件,我想从非日期字段中删除破折号。

我提出了s/([^0-9]+)-([^0-9]+)/$1 $2/g,但只有在字符串中只有一个破折号时才有用,或者我应该说它只会删除一个破折号。

所以我想说:

 2014-05-01
 this-and
 this-and-that
 this-and-that-and-that-too
 2015-01-01

我将使用什么正则表达式来生成

 2014-05-01
 this and
 this and that
 this and that and that too
 2015-01-01

7 个答案:

答案 0 :(得分:5)

不要使用一个正则表达式。不要求单个正则表达式必须包含所有代码的逻辑。

使用一个正则表达式查看它是否为日期,然后使用第二个正则表达式进行转换。如果你把它分成两部分,读者会更清楚(将来就是你)。

#!/usr/bin/perl
use warnings;
use strict;

while ( my $str = <DATA>) {
    chomp $str;
    my $old = $str;
    if ( $str !~ /^\d{4}-\d{2}-\d{2}$/ ) {  # First regex to see if it's a date
        $str =~ s/-/ /g;                    # Second regex to do the transformation
    }
    print "$old\n$str\n\n";
}
__DATA__
2014-05-01
this-and
this-and-that
this-and-that-and-that-too
2015-01-01

运行它会给你:

2014-05-01
2014-05-01

this-and
this and

this-and-that
this and that

this-and-that-and-that-too
this and that and that too

2015-01-01
2015-01-01

答案 1 :(得分:2)

使用look around

$ perl -pe 's/
    (?<!\d)    # a negative look-behind with a digit: \d
    -          # a dash, literal 
    (?!\d)     # a negative look-ahead  with a digit: \d
/ /gx' file

输出

 2014-05-01
 this and
 this and that
 this and that and that too
 2015-01-01

查看一些断言以确保-周围没有数字(在这种情况下)。看看周围没有任何捕获,它只是在那里测试断言。这是一个靠近你的好工具。

检查:

http://www.perlmonks.org/?node_id=518444
http://www.regular-expressions.info/lookaround.html

答案 2 :(得分:1)

丢失+ - 它正在捕捉字符串直到最后-,包括之前的-字符:

s/([^0-9]|^)-+([^0-9]|$)/$1 $2/g;

示例:https://ideone.com/r2CI7v

答案 3 :(得分:1)

只要您的程序在$_变量中单独收到每个字段,您只需要

tr/-/ / if /[^-\d]/

答案 4 :(得分:0)

这应该这样做

$line =~ s/(\D)-/$1 /g;

答案 5 :(得分:0)

正如我在评论中所解释的那样,在编辑数据之前,您确实需要使用Text::CSV将每条记录拆分为字段。这是因为包含空格的数据需要用双引号括起来,所以像this-and-that这样的字段将从空格开始,但是当连字符被转换为空格时需要添加它们。

此程序显示了一个使用您自己的数据的简单示例。

use strict;
use warnings;

use Text::CSV;

my $csv = Text::CSV->new({eol => $/});

while (my $row = $csv->getline(\*DATA)) {
  for (@$row) {
    tr/-/ / unless /^\d\d\d\d-\d\d-\d\d$/;
  }
  $csv->print (\*STDOUT, $row);
}

__DATA__
2014-05-01,this-and-that,this-and-that,this-and-that-and-that-too,2015-01-01

<强>输出

2014-05-01,"this and that","this and that","this and that and that too",2015-01-01

答案 6 :(得分:-1)

如果您想要排除特定表单的更改,您必须包含它们 在搜索时在正则表达式中。否则,你不能确定。

 # s/((?:\d{4}\s*-\s*\d{2}\s*-\s*\d{2}[^\d-]*)*)-((?:[^\d-]*\d{4}\s*-\s*\d{2}\s*-\s*\d{2})*)/$1 $2/g

 (                             # (1 start)
      (?:
           \d{4} \s* - \s* \d{2} \s* - \s* \d{2} 
           [^\d-]* 
      )*
 )                             # (1 end)
 -
 (                             # (2 start)
      (?:
           [^\d-]* 
           \d{4} \s* - \s* \d{2} \s* - \s* \d{2} 
      )*
 )                             # (2 end)