查找在Perl中的大字符串中找到子字符串的行号

时间:2011-02-07 05:12:49

标签: perl line substring

在perl字符串中搜索子字符串的行号的最佳方法是什么?对于e.x。: 在

中搜索“逃脱”
"How to Format
► put returns between paragraphs
► for linebreak add 2 spaces at end
► _italic_ or **bold**
► indent code by 4 spaces
► backtick escapes `like _so_`
► quote by placing > at start of line
► to make links
<http://foo.com>
[foo](http://foo.com)"

应该给出6作为行号。

6 个答案:

答案 0 :(得分:5)

我将如何做到这一点:

my $string = 'How to Format
- put returns between paragraphs
- for linebreak add 2 spaces at end
- _italic_ or **bold**
- indent code by 4 spaces
- backtick escapes `like _so_`
- quote by placing > at start of line
- to make links
<http://foo.com>
[foo](http://foo.com)';

if ($string =~ /escape/) {
  # Count the number of newlines before the match.
  # Add 1 to make the first line 1 instead of 0.
  my $line = 1 + substr($string, 0, $-[0]) =~ tr/\n//;

  print "found at line $line\n";
}

这可以避免执行任何工作计数行,除非实际找到该字符串。它使用@- variable查找匹配开始的位置,然后使用tr计算换行符。

答案 1 :(得分:5)

另一种解决方案的想法。在最近的Perls中,您可以在字符串上打开文件句柄,然后使用特殊的$.变量自动跟踪行号:

open my $handle, '<', \$str;
my $linenum;

while (<$handle>) {
    $linenum = $., last if /escape/;
}

close $handle;

if (defined $linenum) {
    print "Found match on line $linenum\n";
} else {
    print "No match found\n";
}

答案 2 :(得分:3)

$.此特殊变量将为您提供输入文件行号,有关详细信息,请转到http://perldoc.perl.org/perlvar.html

use strict;
use IO::Handle;
my $search = 'escapes';
while (my $line = <DATA>) {
       if ($line =~ /$search/){
            my $line_number = DATA->input_line_number();
        }
}

__DATA__
"How to Format
? put returns between paragraphs
? for linebreak add 2 spaces at end
? _italic_ or **bold**
? indent code by 4 spaces
? backtick escapes `like _so_`
? quote by placing > at start of line
? to make links
<http://foo.com>
[foo](http://foo.com)"

答案 3 :(得分:1)

这假设您的输入文本包含在单个标量中:

my $i = 0;
my $lineno;
for my $line (split(/\n/, $large_block_of_text)) {
 if($line =~ /escape/) {
  $lineno = $i;
  last;
 }
 $i++;
}

if(defined($lineno)) {
 print("'escape' is on line $lineno\n");
} else {
 print("'escape' was not found\n");
}

答案 4 :(得分:0)

我会通过迭代搜索目标模式和换行符的字符串来解决这个问题:

my $str = "<your string above>";
my $linenum = 1;
my $found = 0;

while ($str =~ /(escape)|\n/g) {
    $found = 1, last if defined $1;
    ++$linenum;
}

pos($str) = 0;  # Reset last match position

if ($found) {
    print "Found match on line $linenum\n";
} else {
    print "No match found\n";
}

答案 5 :(得分:0)

从Perl / CGI界面中的文件打印特定行:

open(FILE,"<report_timing.log");
my @list = grep /\bslack\b/, <FILE>;
chomp @list;
print "$_\n<P>" foreach @list;