如何在左括号内的双引号内打印字符串?

  • 本文关键字:打印 字符串 perl
  • 更新时间 :
  • 英文 :

/* start of maker a_b.c[0] */
/* start of maker a_b.c[1] */
maker ( "a_b.c[0]" )
maker ( "a_b.c[1]" )

如何提取双引号内的字符串并将它们存储到数组中?这是我试过的。

open(file, "P2.txt");
@A = (<file>) ;
foreach $str(@A)
{
if($str =~ /"a_b.c"/)
{
print "$str n"; 
} 
} 

注意:只有双引号内的内容必须存储到数组中。如果你在斜杠中看到示例的第一行,你会看到我想要匹配的字符串。那不应该被印出来。因此,只有双引号内的字符串应该存储到数组中。即使相同的字符串在没有双引号的情况下在其他地方重复出现,也不应该被打印。.

这不是关于寻找双引号中的字符串。它是关于定义一个模式(一个正则表达式)来匹配你想要找到的行。

下面是我可以对你的代码做的最小的改变,以使它工作:

open(file, "P2.txt");
@A = (<file>) ;
foreach $str(@A)
{
if($str =~ /"a_b.c/)  # <=== Change here
{
print "$str n"; 
} 
} 

我所做的就是从匹配表达式中删除结束双引号。因为你不关心后面是什么,所以你不需要在正则表达式中指定它。

我应该指出这并不完全正确。在正则表达式中,点具有特殊的含义(它的意思是"匹配此处的任何字符"),因此要匹配实际的点(这正是您想要的),您需要用反斜杠转义点。所以应该是:

if($str =~ /"a_b.c/)

重写以使用一些更现代的Perl实践,我会这样做:

# Two safety nets to find problems in your code
use strict;
use warnings;
# say() is a better print()
use feature 'say';
# Use a variable for the filehandle (and declare it with 'my')
# Use three-arg version of open()
# Check return value from open() and die if it fails
open(my $file, '<', "P2.txt") or die $!;
# Read data directly from filehandle
while ($str = <$file>)
{
if ($str =~ /"a_b.c/)
{
say $str; 
} 
}

你甚至可以使用隐式变量($_)和语句修饰符来使你的循环更简单。

while (<$file>) {
say if /"a_b.c/;
}

查看您提供的示例输入,该任务可以解释为"将单个字符串参数提取到看起来像函数调用的东西"。似乎在c风格的注释中存在不匹配的附加复杂性。请注意perlfaq -q comment。

如FAQ条目所示,忽略任意c风格注释中的内容通常不是微不足道的。我决定尝试C::Tokenize来帮助:

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use C::Tokenize qw( tokenize );
use Const::Fast qw( const );
use Path::Tiny qw( path );
sub is_open_paren {
($_[0]->{type} eq 'grammar') && ($_[0]->{grammar} eq '(');
}
sub is_close_paren {
($_[0]->{type} eq 'grammar') && ($_[0]->{grammar} eq ')');
}
sub is_comment {
$_[0]->{type} eq 'comment';
}
sub is_string {
$_[0]->{type} eq 'string';
}
sub is_word {
$_[0]->{type} eq 'word';
}
sub find_single_string_args_in_invocations {
my ($source) = @_;
my $tokens = tokenize(path( $source )->slurp);
for (my $i = 0; $i < @$tokens; ++$i) {
next if is_comment( $tokens->[$i] );
next unless is_word( $tokens->[$i] );
next unless is_open_paren( $tokens->[$i + 1] );
next unless is_string( $tokens->[$i + 2] );
next unless is_close_paren( $tokens->[$i + 3]);
say $tokens->[$i + 2]->{string};
$i += 3;
}
}
find_single_string_args_in_invocations($ARGV[0]);

,加上你的输入,产生:

C:Temp> perl t.pl test.c
"a_b.c[0]"
"a_b.c[1]"

最新更新