【问题标题】:How do I chomp off everything after a character?我如何在角色之后剔除所有内容?
【发布时间】:2019-09-17 00:20:43
【问题描述】:

我想创建一个 Perl 程序来接收一个文件,并且对于每一行,在某个字符(比如说 /)之后删除所有内容。例如,考虑这个示例文件:

foo1/thing 1.1.1 bar
foo2/item 2.3.2 bar
foo3/thing 3.4.5 bar

我想删除每行斜线后的所有内容并将其打印出来,以便该文件变为:

foo1
foo2
foo3

我尝试使用这个程序,在 foreach 循环中使用 readline,但输出不是我所期望的:

print ( "Enter file name: " ) ;
my $filename = <> ;
$/ = ''
chomp $filename ;

my $file = undef ;
open ( $file, "< :encoding(UTF-8)", $filename
$/ = '/' ;
foreach ( <$file> ) {
    chomp ;
    print ;
}

但这只是删除每行的斜线。

foo1thing 1.1.1 bar
foo2item 2.3.2 bar
foo3thing 3.4.5 bar

我怎样才能改变它以产生我需要的输出?

【问题讨论】:

  • 删除每行第一个或最后一个字符之后的所有内容?
  • 第一个斜线。
  • 使用$/ 不会满足您的需要。该变量设置了被认为是记录结束的内容,可以说是“换行符”。无论设置为什么,readline(又名&lt;&gt;)和chomp 等运算符都会使用它作为“行”结束的标记。所以&lt;&gt; 读取到第一个这样的字符并将其返回为“行”(在标量上下文中),然后再次......你最终不会删除 anything 除了这些字符本身(@ 987654332@ 这里)。当您说“删除每行斜线后的所有内容”时,您的意思是“正常”(通常)意义上的行;那么你不想重新定义什么是“线”。
  • 考虑一个包含字符 abX\nX12X 的文件。打开它,设置$/ = 'X';,然后用while (&lt;$fh&gt;) 读取。 readline (&lt;&gt;) 将读取三个“行”(abX\nX12X),如果您还使用chomp,则这些X 将被删除。

标签: perl


【解决方案1】:

就问题而言,输入记录分隔符 ($/) 不允许使用正则表达式。

您可以按照以下方式进行:

print ( "Enter file name: " ) ;
my $filename = <> ;
chomp $filename ;

open ( my $file, "< :encoding(UTF-8)", $filename ) 
    or die "could not open file $filename: $!";
while ( my $line = <$file> ) {
    $line =~ s{/.*}{}s;
    print "$line\n";
}

Regexp s{/.*}{}s 匹配第一个斜杠和后面的所有内容,并抑制它(以及尾随的新行)。

注意:使用open() 时始终检查错误,如the documentation 中所述:

在打开文件时,如果请求失败,则很少继续,因此open 经常与die 一起使用。

【讨论】:

  • 这不起作用。它产生了与以前相同的结果。
  • @Blue-ManedHawk 你摆脱了$/ 的东西吗?
  • 是的,它成功了!谢谢!那么为什么我需要删除那些东西呢?
  • 因为这使它认为 / 是行尾而不是换行符,所以后面的都是下一行的开头,不受替换的影响
【解决方案2】:
$line =~ s{/.*}{}s;                       # In-place (destructive)

my ($extracted) = $line =~ m{([^/]*)};    # Returns (non-destructive)

【讨论】:

    猜你喜欢
    • 2012-07-09
    • 2020-10-06
    • 2015-06-03
    • 1970-01-01
    • 2017-12-31
    • 1970-01-01
    • 2012-12-07
    • 2019-07-21
    • 1970-01-01
    相关资源
    最近更新 更多