سؤال

أريد تحليل السلاسل، بحيث للتحقق مما إذا كان لديهم بناء جملة محددة أم لا.

مثال:

Str = Z344-R565l t

هنا لمتطلباتي بعد Z يجب أن يكون هناك رقم وبعد ذلك - وبعد ذلك R يجب أن يكون هناك تليها رقم، تليها l, ، تليها مساحة ثم أخيرا t.

إذا كان أي شيء آخر غير هذا يجب أن يكون خطأ.

يجب أن تحليل العديد من أنواع بناء الجملة المختلفة مثل هذا. سأكون محرجا إذا اكتب وظيفة لكل نوع من بناء الجملة مطلوب. سمعت أن yacc أو lex يمكن أن يحل هذه المشكلة.

يمكن لأي شخص يرمي بعض الضوء على مشكلتي؟

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

المحلول

استخدام دفعة :: Regex

#include <string>
#include <boost/regex.hpp>

bool isMatch(std::string input){
    boost::regex r("Z[0-9]*-R[0-9]*l t");
    return boost::regex_search(input, r);
}

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

نصائح أخرى

أنت تفعل هذا مع regex.

Z344-R565L T

يجب أن تبدو Regex الخاص بك شيء مثل هذا. لست متأكدا من مكتبة Regex لاستخدامها ل C ++، ولكن هذا هو Regex العام للتأكد من مطابقات السلسلة الخاصة بك.

Z[0-9]+-R[0-9]+l t

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

rule<> testFormula = 
    (ch_p('Z') >> int_p) 
    >> (ch_p('-')>>ch_p('R')>>int_p>>ch_p('l')) 
    >> space_p >> ch_p('t');

لدي أجزاء معزولة من التعبير الذي قد ترغب في الاتصال ببعض الإجراءات (باستخدام [] المشغل).

انظر توثيق للمزيد من المعلومات

قد جوجل "runtime parser generation" أو شيئا من هذا القبيل...

lex و yacc (أو متساوية جنو flex و bison) القيام بعملهم في تجميع الوقت وقد لا يكون مرنا بما يكفي لاحتياجاتك. (أو قد، أنت لست محددا جدا).

إذا كان لديك مترجم حديث (VC 2008 SP1، وما إلى ذلك)، فلا حاجة لاستخدام دفعة، Regex جزء من TR1 ويمكنك استخدامها باستخدام هذا الرأس: #include <regex>

مثال لتاريخ (يجب عليك استخدام مزدوج \ كما شخصية الهروب):

string dateorder = "12/07/2009";

tr1::regex expr("^([1-2][0-9]|0?[1-9]|30|31)/([1-9]|10|11|12)/(2\\\d{3})$");

if (!regex_match(dateorder.begin(),dateorder.end(),expr))
{
    ...
    break;  
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top