سؤال

أحتاج إلى كتابة برنامج نصي بيرل للقراءة في ملف، وحذف أي شيء داخل <>، حتى لو كانت على خطوط مختلفة. وهذا هو، إذا كان الإدخال هو:

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.

أريد أن يكون الإخراج:

Hello, world. I ate a sandwich. bananas.

أعرف كيفية القيام بذلك إذا كان النص في سطر واحد مع Regex. لكنني لا أعرف كيف أفعل ذلك مع خطوط متعددة. في النهاية، أحتاج إلى أن أكون قادرا على حذف أجزاء من القالب حتى أتمكن من إنشاء ملفات معلمين لملفات التكوين. اعتقدت أن بيرل ستكون لغة جيدة ولكن ما زلت أحصل على تعليق منه.

يحرر: تحتاج أيضا أكثر من مثيل واحد من <>

هل كانت مفيدة؟

المحلول

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

نصائح أخرى

قد ترغب في التحقق من وحدة بيرل النص :: متوازن, ، جزء من التوزيع الأساسي. أعتقد أنه سيكون من المساعدة بالنسبة لك. عموما، يريد المرء تجنب regexes للقيام بهذا النوع من الأشياء إذا كان من المحتمل أن يكون النص الموضوعي مجموعة دخولية من المحددين، فيمكنه الحصول على فوضوي للغاية.

في بيرل:

#! /usr/bin/perl   
use strict;

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

يستبدل Regex أي شيء يبدأ به <من خلال الأول> (شامل) ويستبدله بلا شيء. G هو عالمي (أكثر من مرة).

تحرير: أدمج التعليقات من هايك وفوضى

طريقة غير فعالة

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

نفس البرنامج

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

يعتمد ذلك على كيفية النص الكبير الذي تريده هنا هو الخط المستهلكة لأفعال واحد أكثر فعالية حسب الخط

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

نفس البرنامج

my $a;
while (<>) {
    if ($a) {
        if (s/.*?>//) {
            s/<.*?>//g;
            $a = s/<.*//s;
        }
        else { $_ = q{} }
    }
    else {
        s/<.*?>//g;
        $a = s/<.*//s;
    }
    print;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top