2016-05-26 97 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