كيف أقوم بإجراء استبدال Perl على سلسلة مع الاحتفاظ بالأصل؟

StackOverflow https://stackoverflow.com/questions/22836

  •  09-06-2019
  •  | 
  •  

سؤال

في لغة Perl، ما هي الطريقة الجيدة لإجراء استبدال على سلسلة باستخدام تعبير عادي وتخزين القيمة في متغير مختلف، دون تغيير الأصل؟

عادةً ما أقوم بنسخ السلسلة إلى متغير جديد ثم ربطها بملف s/// regex الذي يقوم بالاستبدال في السلسلة الجديدة، لكنني كنت أتساءل عما إذا كانت هناك طريقة أفضل للقيام بذلك؟

$newstring = $oldstring;
$newstring =~ s/foo/bar/g;
هل كانت مفيدة؟

المحلول

هذا هو المصطلح الذي استخدمته دائمًا للحصول على نسخة معدلة من سلسلة دون تغيير الأصل:

(my $newstring = $oldstring) =~ s/foo/bar/g;

في الإصدار Perl 5.14.0 أو الأحدث، يمكنك استخدام الملف الجديد /r معدل الاستبدال غير المدمر:

my $newstring = $oldstring =~ s/foo/bar/gr; 

ملحوظة:الحلول المذكورة أعلاه تعمل بدون g أيضاً.كما أنها تعمل مع أي معدلات أخرى.

نصائح أخرى

البيان:

(my $newstring = $oldstring) =~ s/foo/bar/g;

وهو ما يعادل:

my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

بدلا من ذلك، اعتبارا من بيرل 5.13.2 يمكنك استخدامه /r للقيام باستبدال غير مدمر:

use 5.013;
#...
my $newstring = $oldstring =~ s/foo/bar/gr;

تحت use strict, ، يقول:

(my $new = $original) =~ s/foo/bar/;

بدلاً من.

يعد الحل ذو السطر الواحد أكثر فائدة باعتباره شعارًا أكثر من كونه رمزًا جيدًا؛سيعرفها مبرمجو لغة Perl الجيدون ويفهمونها، ولكنها أقل شفافية وقابلية للقراءة من مقطع النسخ والتعديل المكون من سطرين الذي بدأت به.

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

حل آخر قبل 5.14: http://www.perlmonks.org/?node_id=346719 (انظر مشاركة يافي)

كما يستخدم نهجه map, ، كما أنه يعمل بشكل جيد مع المصفوفات، ولكنه يتطلب التتالي map لإنتاج مصفوفة مؤقتة (وإلا سيتم تعديل النسخة الأصلية):

my @orig = ('this', 'this sucks', 'what is this?');
my @list = map { s/this/that/; $_ } map { $_ } @orig;
# @orig unmodified

أنا أكره فو وبار..من الذي ابتكر هذه المصطلحات غير الوصفية في البرمجة على أي حال؟

my $oldstring = "replace donotreplace replace donotreplace replace donotreplace";

my $newstring = $oldstring;
$newstring =~ s/replace/newword/g; # inplace replacement

print $newstring;
%: newword donotreplace newword donotreplace newword donotreplace

إذا كتبت بيرل مع use strict;, ، فستجد أن بناء الجملة المكون من سطر واحد غير صالح، حتى عند الإعلان عنه.

مع:

my ($newstring = $oldstring) =~ s/foo/bar/;

لقد حصلت:

Can't declare scalar assignment in "my" at script.pl line 7, near ") =~"
Execution of script.pl aborted due to compilation errors.

بدلاً من ذلك، فإن بناء الجملة الذي كنت تستخدمه، على الرغم من أن السطر أطول، هو الطريقة الصحيحة من الناحية النحوية للقيام بذلك use strict;.بالنسبة لي باستخدام use strict; هي مجرد عادة الآن.أفعل ذلك تلقائيا.يجب على الجميع.

#!/usr/bin/env perl -wT

use strict;

my $oldstring = "foo one foo two foo three";
my $newstring = $oldstring;
$newstring =~ s/foo/bar/g;

print "$oldstring","\n";
print "$newstring","\n";
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top