小编Mik*_*ke 的帖子

如何在Perl中搜索多个文件中的字符串?

我的问题可能很简单,但我是一个完整的新手.我想搜索特定短语的多个文本文件的内容,然后在屏幕上显示查找的行.我已经学会了如何处理单个文件.例如,如果我想搜索一个单词,请在F的根目录中名为"wyvern.txt"的文本文件中说"Okay".以下代码有效:

#!/usr/bin/perl

$file = 'F:\wyvern.txt';
open(txt, $file);
while($line = <txt>) {
  print "$line" if $line =~ /Okay/;
}
close(txt);
Run Code Online (Sandbox Code Playgroud)

但是,如果我想在两个文本文件中搜索相同的短语,分别说"wyvern"和"casanova",或者如何在F的根目录中的"novels"目录中查找所有文件,该怎么办?

任何帮助将不胜感激.提前致谢

麦克风

编辑:

哈哈,我终于想出了如何搜索目录中的所有文件以进行模式匹配:)以下代码效果很好:

#!/usr/bin/perl  
@files = <F:/novels/*>;
foreach $file (@files) {
open   (FILE, "$file");
while($line= <FILE> ){
print "$line" if $line =~ /Okay/;
}
close FILE; 
} 
Run Code Online (Sandbox Code Playgroud)

perl

11
推荐指数
1
解决办法
3万
查看次数

为什么我的非贪婪Perl正则表达式仍然匹配太多?

说,我有一行包含以下字符串:

"$tom" said blah blah blash.  "$dick" said "blah blah blah". "$harry" said blah blah blah.

我想提取

"$dick" said "blah blah blah"

我有以下代码:

my ($term) = /(".+?" said ".+?")/g;
print $term;
Run Code Online (Sandbox Code Playgroud)

但它给了我超过我需要的东西:

"$tom" said blah blah blash.  "$dick" said "blah blah blah"

我尝试使用非捕获的parens将我的模式整体分组:

my ($term) = /((?:".+?" said ".+?"))/g;
Run Code Online (Sandbox Code Playgroud)

但问题仍然存在.

我重新阅读了学习Perl的Nongreedy Quantifiers部分,但到目前为止我无处可去.

感谢您提供的任何指导,您可以慷慨地提供:)

regex perl

9
推荐指数
1
解决办法
5425
查看次数

如何让PCRE与C++一起使用?

这是一个新手问题,但我希望我能尽可能清楚地表达我的问题.

我正在尝试用C++进行模式匹配.

我从这里下载了WinRE 版本的PCRE,并将下载的pcre3.dll和pcreposix3.dll文件放入Dev-CPP的lib文件夹(我使用的是Bloodshed Dev-C++ 4.9.9 IDE).

我还下载了一个pcrecpp.h头文件,并将它放在同一个目录中,我正在编写以下代码(实际上并没有写.我正在处理一个名为PCRE-Perl Compatible Regular Express的PDF教程中的示例代码).

但我无法让它发挥作用.代码如下:

    #include <iostream>
    #include <string>
    #include <pcrecpp.h>

    using namespace std;

    int main()
    {
       int i;
       string s;
       pcrecpp::RE re("(\\w+):(\\d+)");
       if (re.error().length() > 0) {
          cout << "PCRE compilation failed with error: " << re.error() << "\n";
       }
       if (re.PartialMatch("root:1234", &s, &i))
       cout << s << " : " << i << "\n";
    }
Run Code Online (Sandbox Code Playgroud)

当我编译代码时,Dev-C++给了我很多错误,包括:"`pcrecpp'尚未声明"和"RE"未声明.

我该如何处理下载的文件并修复我的问题?或者有什么明显的东西让我失踪?

c++ pcre

9
推荐指数
1
解决办法
1万
查看次数

如何在Perl中将输入文件转换为UTF-8编码?

我已经知道如何将文件的非utf8编码内容逐行转换为UTF-8编码,使用类似下面的代码:

# outfile.txt is in GB-2312 encode    
open my $filter,"<",'c:/outfile.txt'; 

while(<$filter>){
#convert each line of outfile.txt to UTF-8 encoding   
    $_ = Encode::decode("gb2312", $_); 
...}
Run Code Online (Sandbox Code Playgroud)

但我认为Perl可以直接将整个输入文件编码为UTF-8格式,所以我尝试了类似的东西

#outfile.txt is in GB-2312 encode
open my $filter,"<:utf8",'c:/outfile.txt'; 
Run Code Online (Sandbox Code Playgroud)

(Perl说像"utf8"\ xD4"没有映射到Unicode")

open my $filter,"<",'c:/outfile.txt'; 
$filter = Encode::decode("gb2312", $filter); 
Run Code Online (Sandbox Code Playgroud)

(Perl在未打开的文件句柄上说"readline()!"

它们不起作用.但有没有办法直接将输入文件转换为UTF-8编码?

更新:

看起来事情并不像我想象的那么简单.我现在可以以环形方式将输入文件转换为UTF-8代码.我首先打开输入文件,然后将其内容编码为UTF-8,然后输出到新文件,然后打开新文件以进行进一步处理.这是代码:

open my $filter,'<:encoding(gb2312)','c:/outfile.txt'; 
open my $filter_new, '+>:utf8', 'c:/outfile_new.txt'; 
print $filter_new $_ while <$filter>; 
while (<$filter_new>){
...
} 
Run Code Online (Sandbox Code Playgroud)

但这是太多的工作,它比简单地逐行编码$ filter的内容更麻烦.

unicode perl utf-8 character-encoding

7
推荐指数
1
解决办法
9433
查看次数

我们可以在Perl中同时运行两个非嵌套循环吗?

我的部分代码是这样的:

while(1){
        my $winmm = new Win32::MediaPlayer;   
        $winmm->load('1.mp3'); $winmm->play; $winmm->volume(100);
        Do Some Stuff;
        last if some condition is met;
    }
Run Code Online (Sandbox Code Playgroud)

问题是:当我在while循环中的Do Some Stuff阶段时,我希望音乐始终打开.但是音乐的长度很短,在我进入下一个阶段之前它会完全停止,所以我希望音乐重演,但Win32 :: Mediaplayer模块似乎没有重复模式,所以我想为音乐播放部分做一个无限循环.像这样:

while(1){
 my $winmm = new Win32::MediaPlayer;   
 $winmm->load('1.mp3'); $winmm->play; $winmm->volume(100);
}
while(2){
Do some stuff;
last if some condition is met
}
Run Code Online (Sandbox Code Playgroud)

但根据我目前的Perl知识,如果我在while(1)部分,我永远不会去while(2)部分.即使它涉及到嵌套循环,我也必须做一些事情来突破内部循环,然后再转到外部循环的其他部分.

我的问题的答案"我们可以在Perl中同时运行两个非嵌套循环吗?" 可能是NO,但我认为有一些方法可以处理这种情况.如我错了请纠正我.

一如既往地感谢任何意见/建议:)

UPDATE

我非常感谢大家的帮助.谢谢:)所以我的问题的答案是肯定的,而不是否定的.我很高兴我已经学会了如何使用fork()和线程来解决一个真正的问题:)

perl loops simultaneous

7
推荐指数
2
解决办法
1582
查看次数

在Perl中,while循环通常比for循环快吗?

我已经完成了一个小实验,如下所示,看起来while循环比Perl中的for循环更快.但由于实验相当粗糙,而且主题可能比看上去复杂得多,我想听听你对此有何看法.一如既往地感谢任何意见/建议:)

在以下两个小脚本中,我分别尝试while和for循环来计算100,000的阶乘.具有while循环的那个用了57分17秒完成,而for循环等效花了1小时7分54秒.

具有while循环的脚本:

use strict;
use warnings;
use bigint;

my $now = time;

my $n = shift;
my $s = 1;

while(1){
$s *= $n;
$n--;
last if $n==2;
}

print $s*$n;
$now = time - $now;
printf("\n\nTotal running time: %02d:%02d:%02d\n\n", int($now / 3600),
            int(($now % 3600) / 60), int($now % 60));
Run Code Online (Sandbox Code Playgroud)

有for循环的脚本:

use strict;
use warnings;
use bigint;

my $now = time;

my $n =shift;
my $s=1;

for (my $i=2; $i<=$n;$i++) {
$s = $s*$i;
}

print $s;
$now …
Run Code Online (Sandbox Code Playgroud)

perl performance for-loop while-loop

6
推荐指数
3
解决办法
3415
查看次数

使用Perl逐行连接两个文件有多少种不同的方法?

假设file1看起来像这样:

bye bye
hello
thank you

而file2看起来像这样:

chao
hola
gracias

所需的输出是这样的:

bye bye chao
hello hola
thank you gracias

我自己已经提出了五种不同的方法来解决这个问题.但我认为必须有更多的方法,可能更简洁,更优雅的方式,我希望我能学到更多很酷的东西:)

以下是我迄今为止所尝试的内容,基于我从之前问题的许多解决方案中学到的内容.此外,我正试图消化或内化我从Llama书中获得的知识.

代码1:

#!perl
use autodie;
use warnings;
use strict;

open my $file1,'<','c:/file1.txt';
open my $file2,'<','c:/file2.txt';

while(defined(my $line1 = <$file1>)
        and defined(my $line2 = <$file2>)){
    die "Files are different sizes!\n" unless eof(file1) == eof(file2);
    $line1 .= $line2;
    $line1 =~ s/\n/ /;
    print "$line1 \n";
}
Run Code Online (Sandbox Code Playgroud)

代码2:

#!perl
use autodie;
use warnings;
use strict;

open my $file1,'<','c:/file1.txt';
my @file1 = <$file1>;

open …
Run Code Online (Sandbox Code Playgroud)

perl concatenation

5
推荐指数
3
解决办法
5089
查看次数

如何为简单的Perl词典应用程序正确格式化纯文本数据?

我有一个非常简单的字典应用程序,可以搜索和显示.它是用Win32::GUI模块构建的.我将该字典所需的所有纯文本数据放在该__DATA__部分下.该脚本本身非常小,但该__DATA__部分下的所有内容,其大小达到30 MB.为了与我的朋友分享工作,然后我使用PAR::Packer具有最高压缩级别9 的模块的PP实用程序将脚本打包到一个独立的可执行文件中,现在我有一个大小相当的单文件字典应用程序17MB

但是,尽管我对单文件脚本的想法非常满意,但是在脚本的DATA部分下放置如此大量的文本数据并不合适.首先,当我尝试在Padre中打开脚本时(Notepad ++没问题),我收到的错误是:

Can't open my script as the script is over the arbitrary file size limit which is currently 500000.


我的问题:

如果我将DATA部分下的所有内容移到单独的文本文件中,除了消除Padre的文件打开问题之外,它是否带给我额外的好处?

如果我这样做,我该怎么做才能减小单独文件的大小?拉链并在搜索和显示时解压缩?

人们通常如何格式化字典应用程序所需的文本数据?

有任何意见,想法或建议吗?总是如此谢谢:)

perl dictionary

5
推荐指数
1
解决办法
245
查看次数

我可以在Perl中更改已加载模块中的代码行吗?

当我使用FLV::Info模块从多个FLV文件中提取元数据或合并多个FLV文件时,我经常收到"标签大小太小"错误,然后模块将拒绝工作.三年前有人在这里发布了一个错误报告,但似乎没有修复.

好吧,最近我发现如果我只是在Tag.pm中注释掉以下代码行,这是一个FLV::Info依赖模块,如下所示:

=pod
if ($datasize < 11)
   {
      die "Tag size is too small ($datasize) at byte " . $file->get_pos(-10);
   }
=cut
Run Code Online (Sandbox Code Playgroud)

FLV::Info 然后将按预期方便地完成工作.

我不确定这是一个非常愚蠢的问题,但我感到很好奇:

是否有一种简单的方法可以在不修改原始.pm文件的情况下更改已加载模块中的几行代码?

有什么想法,建议或意见吗?总是如此谢谢:)

UPDATE

非常感谢@Shwern.你的答案非常令人满意:)还要感谢@DVK的建议和"猴子补丁"一词和@brian的书籍推荐.

这是我对样本FLV文件测试的反馈,如果我使用原始模块而不对其执行任何操作,则会导致"标记大小太小"错误.

"eval it back"方法解决了这个问题

use FLV::Info;

use Data::Dump::Streamer;
my $original = FLV::Tag->can("parse");
my $code = Dump($original)->Out;
#$code =~ s{\Qif ($datasize < 11)\E}{if (0)}; #This somehow won't work
$code =~ s{die "Tag}{warn "Tag}; #Let it warn but not die

no warnings 'redefine';
*FLV::Tag::parse = …
Run Code Online (Sandbox Code Playgroud)

perl module

5
推荐指数
1
解决办法
282
查看次数

如何打印匹配的行,紧靠其上方的一行和紧接下方的一行?

根据Bi提出的相关问题,我已经学会了如何打印匹配的线以及它下方的线.代码看起来很简单:

#!perl
open(FH,'FILE');
while ($line = <FH>) {
    if ($line =~ /Pattern/) {
        print "$line";
        print scalar <FH>;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我在谷歌搜索了一个不同的代码,可以打印匹配的行与它们正上方的行.部分适合我的目的的代码是这样的:

#!perl

@array;
open(FH, "FILE");
while ( <FH> ) {
  chomp;
  $my_line = "$_";
  if ("$my_line" =~ /Pattern/) {
      foreach( @array ){
          print "$_\n";
      }
      print "$my_line\n"
  }
  push(@array,$my_line);
  if ( "$#array" > "0" ) {
    shift(@array);
  }
};
Run Code Online (Sandbox Code Playgroud)

问题是我仍然无法弄清楚如何一起做这些.似乎我的大脑正在关闭.有没有人有任何想法?

谢谢你的帮助.

更新:

我觉得我有点感动.你们这么有帮助!也许有点偏离主题,但我真的觉得有更多的冲动.

我需要一个Windows程序,能够搜索多个文件的内容并显示相关信息,而无需单独打开每个文件.我尝试使用谷歌搜索和两个应用程序,代理Ransack和Devas,已证明是有用的,但它们只显示包含匹配查询的行,我想要查看相邻的行.然后,即兴创作一个程序的想法突然出现在我脑海中.多年前,我对Perl脚本印象深刻,可以生成维基百科的Tomeraider格式,这样我就可以轻松地在我的Lifedrive上搜索Wiki,而且我也在网上读到了Perl很容易学习的地方,特别是像我这样的人没有任何编程语言的经验.然后我几天前就开始自学Perl了.我的第一步是学习如何完成与"Agent Ransack"相同的工作,并且使用Perl证明它并不那么困难.我首先学习了如何搜索单个文件的内容并通过修改标题为"Perl by Example"的书中使用的示例来显示匹配的行,但我被困在那里.我对如何处理多个文件变得完全无能为力.书中没有找到类似的例子,也可能是因为我太不耐烦了.然后我再次尝试谷歌搜索并被带到这里,我问了我的第一个问题"如何在Perl中搜索多个文件中的字符串模式?" 在这里,我必须说这个论坛是血腥的真棒;).然后我查看了更多示例脚本,然后我昨天提出了以下代码,它很好地满足了我原来的目的:

代码如下:

#!perl

$hits=0;
print "INPUT YOUR QUERY:";
chop ($query = <STDIN>);
$dir …
Run Code Online (Sandbox Code Playgroud)

perl

4
推荐指数
4
解决办法
2万
查看次数