2009-04-10 41 views
5

Tôi cần viết kịch bản Perl để đọc trong một tệp và xóa mọi thứ bên trong <>, ngay cả khi chúng ở trên các dòng khác nhau. Nghĩa là, nếu đầu vào là:Làm cách nào để xóa các ký tự trong khoảng từ < and > trong Perl?

Hello, world. I <enjoy eating 
bagels. They are quite tasty. 
I prefer when I ate a bagel to 
when I >ate a sandwich. <I also 
like >bananas. 

Tôi muốn đầu ra là:

Hello, world. I ate a sandwich. bananas. 

tôi biết làm thế nào để làm điều này nếu văn bản là 1 phù hợp với một regex. Nhưng tôi không biết làm thế nào để làm điều đó với nhiều dòng. Cuối cùng, tôi cần phải có khả năng xóa các phần của mẫu để có thể tạo các tệp tham số cho các tệp cấu hình. Tôi nghĩ perl sẽ là một ngôn ngữ tốt nhưng tôi vẫn nhận được hang của nó.

Sửa: Cũng cần nhiều hơn 1 thể hiện của <>

Trả lời

4
local $/; 
my $text = <>; 
s/<.*?>//gs; 
print $text; 
+0

Nếu chuỗi của bạn trông giống như sau: ghi>, regex của bạn để lại 'ghi>'.Nếu các dấu ngoặc lồng nhau hoặc trốn thoát và các trường hợp nghịch đảo khác "không bao giờ xảy ra" thì regex vẫn ổn. Để xử lý các trường hợp ngược, sử dụng Text :: Balanced, mặc dù giao diện là lạ. – daotoad

6

Bạn có thể muốn kiểm tra một module Perl Text::Balanced, một phần của sự phân bố cốt lõi. Tôi nghĩ nó sẽ giúp ích cho bạn. Nói chung, người ta muốn tránh các regex để làm điều đó loại NẾU văn bản chủ đề có khả năng có một tập hợp các dấu phân cách bên trong, nó có thể rất lộn xộn.

+0

lời khuyên tốt, nhưng không cần thiết trong trường hợp này. Chắc chắn sẽ ghi nhớ mặc dù. – rlbond

6

Trong Perl:

#! /usr/bin/perl 
use strict; 

my $text = <>; 
$text =~ s/<[^>]*>//g; 
print $text; 

Các regex thay thế bất cứ điều gì bắt đầu với một < qua là người đầu tiên> (bao gồm) và thay thế nó bằng gì. G là toàn cục (nhiều lần).

EDIT: kết hợp ý kiến ​​từ Hynek và hỗn loạn

+0

+1 Đẹp (hoàn thành) ví dụ! –

+0

Hơi không hiệu quả chút nào. Để chia nhỏ và tham gia lại. perl -0777 -pe 's/<[^>] *> // gm' –

+0

công cụ sửa đổi/m không giúp ích gì. Nó có nghĩa là 'đối xử như nhiều người', tức là kết hợp^và $ ở dòng mới, không phải 'đây là đa dòng'./s, coi như một dòng, thực sự là những gì bạn muốn, nhưng bạn không cần nó vì mẫu của bạn không quan tâm đến khoảng trắng. – chaos

1

không hiệu quả một lót cách

perl -0777 -pe 's/<.*?>//gs' 

tương tự như chương trình

local $/; 
my $text = <>; 
s/<.*?>//gs; 
print $text; 

Nó phụ thuộc văn bản lớn như thế nào mà bạn muốn chuyển đổi ở đây là hiệu quả hơn đường tiêu thụ một dòng theo dòng

perl -pe 'if ($a) {(s/.*?>// and do {s/<.*?>//g; $a = s/<.*//s;1}) or $_=q{}} else {s/<.*?>//g; $a = s/<.*//s}' 

tương tự như chương trình

my $a; 
while (<>) { 
    if ($a) { 
     if (s/.*?>//) { 
      s/<.*?>//g; 
      $a = s/<.*//s; 
     } 
     else { $_ = q{} } 
    } 
    else { 
     s/<.*?>//g; 
     $a = s/<.*//s; 
    } 
    print; 
} 
+0

Như đã lưu ý câu trả lời của CoverosGene,/m là không cần thiết hoặc hữu ích. – chaos

+0

Có, bạn đã đúng. –

Các vấn đề liên quan