كيف يمكنني إصلاح التعبير العادي الخاص بي حتى لا يتطابق كثيرًا مع مُحدِّد الكمية الجشع؟[ينسخ]

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

سؤال

هذا السؤال لديه بالفعل إجابة هنا:

لدي السطر التالي:

"14:48 say;0ed673079715c343281355c2a1fde843;2;laka;hello ;)"

أقوم بتحليل هذا باستخدام تعبير عادي بسيط:

if($line =~ /(\d+:\d+)\ssay;(.*);(.*);(.*);(.*)/) {
    my($ts, $hash, $pid, $handle, $quote) = ($1, $2, $3, $4, $5);
}

لكن ال ؛في النهاية أفسدت الأمور ولا أعرف السبب.ألا ينبغي للمشغل الجشع أن يتعامل مع "كل شيء"؟

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

المحلول

يحاول المشغل الجشع الاستيلاء على أكبر قدر ممكن من الأشياء ويظل مطابقًا للسلسلة.ما يحدث هو أن الأول (بعد كلمة "say") يمسك "0ed673079715c343281355c2a1fde843;2"، والثاني يأخذ "laka"، والثالث يعثر على "hello"، والرابع يطابق الأقواس.

ما عليك فعله هو جعل كل شيء ما عدا الأخير غير جشع، بحيث ينتزعون أقل قدر ممكن ويظلون مطابقين للسلسلة:

(\d+:\d+)\ssay;(.*?);(.*?);(.*?);(.*)

نصائح أخرى

(\d+:\d+)\ssay;([^;]*);([^;]*);([^;]*);(.*)

يجب أن تعمل بشكل أفضل

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

بدلاً من ذلك، أقترح شيئًا كهذا:

$x="14:48 say;0ed673079715c343281355c2a1fde843;2;laka;hello ;)";

if (($ts,$rest) = $x =~ /(\d+:\d+)\s+(.*)/)
{
    my($command,$hash,$pid,$handle,$quote) = split /;/, $rest, 5;
    print join ",", map { "[$_]" } $ts,$command,$hash,$pid,$handle,$quote
}

وينتج عنه:

[14:48],[say],[0ed673079715c343281355c2a1fde843],[2],[laka],[hello ;)]

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

حاول صنع أول 3 (.*) غير الجشع (.*?)

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

(\d+:\d+)\ssay;([a-f0-9]+);(\d+);(\w+);([^;\r\n]+)

يمكنك جعل * غير جشع عن طريق إضافة علامة استفهام:

$line =~ /(\d+:\d+)\ssay;(.*?);(.*?);(.*?);(.*)/

أو يمكنك مطابقة كل شيء باستثناء الفاصلة المنقوطة في كل جزء باستثناء الأخير:

$line =~ /(\d+:\d+)\ssay;([^;]*);([^;]*);([^;]*);(.*)/
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top