كيف يمكنني الحفاظ على المسافات عندما تطابق واستبدال عدة كلمات في بيرل؟

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

  •  07-07-2019
  •  | 
  •  

سؤال

ودعونا نقول لدي بعض النص الأصلي:

here is some text that has a substring that I'm interested in embedded in it.

وأنا في حاجة إلى النص لتتناسب جزءا منه، ويقول: "has a substring"

ولكن، قد يكون النص الأصلي وسلسلة مطابقة الخلافات المسافات الفارغة. على سبيل المثال قد يكون النص المباراة:

has a
substring

أو

has  a substring

و / أو النص الأصلي قد يكون:

here is some
text that has
a substring that I'm interested in embedded in it.

وماذا أحتاج برنامجي لإخراج هو:

here is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.

وأنا أيضا بحاجة للحفاظ على نمط مسافة بيضاء في النص الأصلي وأضيف بداية ونهاية علامات لذلك.

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

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

المحلول

وكانت بعض الوقت منذ لقد استعملت بيرل التعابير العادية، ولكن ماذا عن:

$match = s/(has\s+a\s+substring)/[$1]/ig

وهذا من شأنه التقاط صفر أو أكثر الشخصيات المسافات البيضاء والسطر الجديد بين الكلمات. وسوف التفاف المباراة بأكملها مع أقواس مع الحفاظ على الفصل الأصلي. انها ليست تلقائية، ولكنه عمل.

هل يمكن أن تلعب مباريات مع هذا، مثل أخذ "has a substring" سلسلة والقيام التحويل على لجعله "has\s*a\s*substring" لجعل هذا قليلا أقل إيلاما.

تعديل : ل. تعليقات تأسست ysth بأن \ ق metacharacter مباريات أسطر جديدة وهوبز تصويبات لبلدي \ ق الاستخدام

نصائح أخرى

وهذا النمط سوف تطابق السلسلة التي كنت تبحث لتجد:

(has\s+a\s+substring)

وهكذا، عندما يقوم المستخدم بإدخال سلسلة بحث، استبدال أي بيضاء في سلسلة البحث مع \s+ ولديك أسلوبك. و، مجرد استبدال كل مباراة مع [match starts here]$1[match ends here] حيث $1 غير مطابقة النص.

في regexes، يمكنك استخدام + على أنها تعني "واحد أو أكثر من ذلك." ذلك شيء من هذا القبيل

/has\s+a\s+substring/

ومباريات has تليها واحدة أو أكثر من حرف مسافة بيضاء، تليها a تليها واحدة أو أكثر من حرف مسافة بيضاء، تليها substring.

وضعه جنبا إلى جنب مع المشغل الاستبدال، يمكنك أن تقول:

my $str = "here is some text that has     a  substring that I'm interested in embedded in it.";
$str =~ s/(has\s+a\s+substring)/\[match starts here]$1\[match ends here]/gs;

print $str;

والإخراج هو:

here is some text that [match starts here]has     a  substring[match ends here] that I'm interested in embedded in it.

وهناك العديد من اقترح، واستخدام \s+ لمباراة بيضاء. هنا هو كيف نفعل ذلك اوتوماتيكيا:

my $original = "here is some text that has a substring that I'm interested in embedded in it.";
my $search = "has a\nsubstring";

my $re = $search;
$re =~ s/\s+/\\s+/g;

$original =~ s/\b$re\b/[match starts here]$&[match ends here]/g;

print $original;

وإخراج:

<اقتباس فقرة>   

وhere is some text that [match starts here]has a substring[match ends here] that I'm interested in embedded in it.

وقد ترغب في الهروب من أي حرفا ميتا في السلسلة. اذا كان هناك من يهتم، ويمكنني أن إضافته.

وهذا مثال كيف يمكن أن تفعل ذلك.

#! /opt/perl/bin/perl
use strict;
use warnings;

my $submatch = "has a\nsubstring";

my $str = "
here is some
text that has
a substring that I'm interested in, embedded in it.
";

print substr_match($str, $submatch), "\n";

sub substr_match{
  my($string,$match) = @_;

  $match =~ s/\s+/\\s+/g;

  # This isn't safe the way it is now, you will need to sanitize $match
  $string =~ /\b$match\b/;
}

وهذا لا حاليا أي شيء للتحقق من متغير $match لشخصيات غير آمنة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top