2016-05-26 63 views
1

我正在运行一个简单的Perl脚本,它复制了所有以\txt开头到\xtx的行。到现在为止还挺好。Perl脚本搜索/替换和转换结果

use strict; 
use warnings;  

$^I = '.bak'; 

while (<>) { 

    s/(\\txt)(.*)/$1$2\n\\xtx $2/g; 

    print; 
} 

现在我想“擦洗”所有的新线开始\\xtx

  1. 删除所有非单词字符:即非字母,但保持字符,任何字符变音符号

  2. 将所有内容转换为小写。

而这正是我的基本的编程技能结束

我的文本文件看起来像这样:

\txt Text (.) with [ symbols and Num[bers (.2) and cháractẽrs with diacrítics 
\abc More text ... 

我的剧本至今生产:

\txt Text (.) with [ symbols and Num[bers (.2) and cháractẽrs with diacrítics 
\xtx Text (.) with [ symbols and Num[bers (.2) and cháractẽrs with diacrítics 
\abc More text ... 

而且我想实现:

\txt Text (.) with [ symbols and Num[bers (.2) and cháractẽrs with diacrítics 
\xtx text with symbols and numbers and cháractẽrs with diacrítics 
\abc More text ... 

任何帮助非常感谢!

编辑:
这里有一个真实的例子字符串:

\_sh v3.0 400 Text3 

\ref 2013-05-01_08.36.14 001 
\txt Djawy (.) de osẽ[ma (.2) EDJu:: 
\fts Te equivocaste, saliste, 
\fte 

\ELANParticipant #TBGD 
\ELANBegin 00:00:05.367 
\ELANEnd 00:00:06.521 
\dt 26/May/2016 

\ref 2013-05-01_08.36.14 002 
\txt [A;;;;;;;;;;;;; 
\fts A;;;;;;;;;;;;; 
\fte 
... 

...一切都应该保持原样,除了开始\ TXT线...

+0

'重复所有行开始\ txt' ='S/^(\\ TXT)(。*)/ $ 1 $ 2 \ n \\ xtx $ 2/mg' – sln

+0

您需要使用///例如'eval表单来执行此操作。通过空格保存/缩小格式将会有点乏味,但是可行。 – sln

+0

您能否提供真实的示例字符串,因为我认为您的描述不是很清楚。 –

回答

2

你可以试试这个转换版为

的Perl

use strict; 
use warnings; 

binmode (DATA, ":utf8"); 
binmode (STDOUT, ":utf8"); 

while (<DATA>) { 
    s/^(\\txt)(.*)/GetConvetedLine($1,$2)/me; 
    print; 
} 

sub GetConvetedLine 
{ 
    my ($txt, $body) = @_; 
    my $newbody = $body; 
    $newbody =~ s/[^\pL\s]+//g; 
    $newbody =~ s/\s+/ /g; 
    $newbody = lc($newbody); 
    return $txt . $body . "\n" . "\\xtx " . $newbody; 
} 


__DATA__  
\txt Text (.) with [ symbols and Num[bers (.2) and cháractẽrs with diacrítics 

输出

\txt Text (.) with [ symbols and Num[bers (.2) and cháractẽrs with diacrítics 
\xtx text with symbols and numbers and cháractẽrs with diacrítics 
+0

谢谢!,这看起来好像它会这样做!你介意解释一下,我怎样才能将输出打印到原始文件中(就像在原始的例子中那样)?我可以说'perl script.pl myfile.txt'抱歉,如果这应该是显而易见的,但是我是perl的初学者:/ – jan

+0

“......寻求的人应该找到...” - 我想我已经想通了......我把下面的代码放在了下面,当你得到如果我犯了很大的错误,你会不会介意快速检查? (它会产生正确的输出,所以我想一切都很好)非常感谢你的帮助! – jan

1

您可以重构它有点,所以你不必把它全部放到一个正则表达式:

use strict; 
use warnings;  
$^I = '.bak'; 
while (<>) { 
    print; 
    if(/^\\txt/) { 
     s/^\\txt//; # remove \txt 
     s/[\[\]\(\)//g; # remove all unwanted characters 
     print "\xtx $_"; 
    } 
    print; 
} 
+0

感谢您关注此事!但是这个脚本也复制了其他所有行。我也无法让它去除符号字符。 – jan

1

根据记录,这是SLN的回答上面,我结束了使用的(略有修改)的版本。它可被调用,我用于调用与perl script.pl myfile.txt原始脚本相同的方式:

#!/usr/bin/perl 

use strict; 
use warnings; 
use open qw(:std :utf8); 
$^I = '.bak'; # create a backup copy 

while (<>) { 
    s/^(\\txt)(.*)/GetConvetedLine($1,$2)/me; 
    print; 
} 

sub GetConvetedLine 
{ 
    my ($txt, $body) = @_; 
    my $newbody = $body; 
    $newbody =~ s/[^\pL\s]+//g; 
    $newbody =~ s/ \s+/ /g; 
    $newbody = lc($newbody); 
    return $txt . $body . "\n" . "\\xtx " . $newbody; 
} 
+0

是的,它看起来不错。你不需要在GetConvertedLine()中打印,我会使用'$ newbody =〜s/\ s +// g;'就像原文一样。 '\ R'表示换行符。基本上,$ newbody中从来没有任何换行符,因为这是来自'(。*)'的匹配,意思是匹配任何东西_except_ linebreaks。 – sln

+0

谢谢@sln。我已经放了\ R,因为出于某种原因,我会在'$ newbody'的末尾得到一些奇怪的“Windows”换行符(可能是由于原始文件的回车),然后下一行(取决于文本编辑器)不在下一行了。 R似乎摆脱了他们。但是我现在发现了一个更好的解决方案,它搜索's/\ s +// g;'(即\ s +'之前的空格)。这将摆脱这个问题。 – jan