ما هي الطرق المختلفة لتحليل السلاسل في جافا؟[مغلق]

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

  •  08-06-2019
  •  | 
  •  

سؤال

لتحليل أوامر المشغل، غالبًا ما استخدمت ملف ينقسم طريقة لتقسيم سلسلة بواسطة محددات ثم معرفة الباقي من خلال سلسلة من ifق أو switchوفاق.ما هي بعض الطرق المختلفة لتحليل السلاسل في جافا؟

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

المحلول

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

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

نصائح أخرى

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

أود أن أقترح عليك التحقق من ذلك http://www.regular-expressions.info للحصول على مقدمة جيدة للتعبيرات المنطقية، بالإضافة إلى أمثلة محددة لـ Java.

التحليل اليدوي ممتع للغاية..في البداية:)

من الناحية العملية، إذا لم تكن الأوامر معقدة جدًا، فيمكنك التعامل معها بنفس الطريقة المستخدمة في مترجمات سطر الأوامر.هناك قائمة بالمكتبات التي يمكنك استخدامها: http://java-source.net/open-source/command-line.أعتقد أنك يمكن أن تبدأ مع أباتشي المشاعات CLI أو args4j (يستخدم التعليقات التوضيحية).إنها موثقة جيدًا وسهلة الاستخدام حقًا.إنهم يتعاملون مع التحليل تلقائيًا والشيء الوحيد الذي عليك فعله هو قراءة حقول معينة في كائن ما.

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

أود أن أنظر هجرات جافا ل زورك, ، وتميل نحو بسيطة معالج اللغة الطبيعية (مدفوعة إما عن طريق الرمز المميز أو التعبير العادي) مثل ما يلي (من هذا الرابط):

    public static boolean simpleNLP( String inputline, String keywords[])
    {
        int i;
        int maxToken = keywords.length;
        int to,from;
        if( inputline.length() = inputline.length()) return false; // check for blank and empty lines
        while( to >=0 )
        {
            to = inputline.indexOf(' ',from);
            if( to > 0){
                lexed.addElement(inputline.substring(from,to));
                from = to;
                while( inputline.charAt(from) == ' '
                && from = keywords.length) { status = true; break;}
            }
        }
        return status;
    }

...

أي شيء يعطي المبرمج سببًا للنظر إلى Zork مرة أخرى هو أمر جيد في كتابي، فقط احترس من Grues.

...

توصي Sun نفسها بالابتعاد عن StringTokenizer واستخدام طريقة String.spilt بدلاً من ذلك.

ستحتاج أيضًا إلى إلقاء نظرة على فئة النمط.

تصويت آخر لصالح ANTLR/ANTLRWorks.إذا قمت بإنشاء نسختين من الملف، أحدهما يحتوي على كود Java لتنفيذ الأوامر فعليًا، والآخر بدون (مع القواعد النحوية فقط)، فستكون لديك مواصفات قابلة للتنفيذ للغة، وهو أمر رائع للاختبار، ونعمة للتوثيق ، وموفرًا كبيرًا للوقت إذا قررت نقله.

إذا كان هذا لتحليل أسطر الأوامر، أود أن أقترح استخدام كومنز كلي.

توفر مكتبة Apache Commons CLI واجهة برمجة التطبيقات (API) لمعالجة واجهات سطر الأوامر.

يحاول جافاCC مولد محلل لجافا.

يحتوي على الكثير من الميزات لترجمة اللغات، وهو مدعوم جيدًا على Eclipse.

@CodingTheWheel إليك الكود الخاص بك، مع القليل من التنظيف ومن خلال Eclipse (كنترول+يحول+F) وإدراجها مرة أخرى هنا :)

بما في ذلك المساحات الأربعة التي أمام كل سطر.

public static boolean simpleNLP(String inputline, String keywords[]) {
    if (inputline.length() < 1)
        return false;

    List<String> lexed = new ArrayList<String>(); 
    for (String ele : inputline.split(" ")) {
        lexed.add(ele);
    }


    boolean status = false;
    to = 0;
    for (i = 0; i < lexed.size(); i++) {
        String s = (String) lexed.get(i);
        if (s.equalsIgnoreCase(keywords[to])) {
            to++;
            if (to >= keywords.length) {
                status = true;
                break;
            }
        }
    }
    return status;
}

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

فيما يلي مثال لاستخدام الرمز المميز:

String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;

if (tokens.hasMoreTokens()) {
    action = tokens.nextToken();
}

if (action != null) {
    doCommand(action, tokens);
}

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

عندما تكون السلسلة الفاصلة للأمر دائمًا هي نفس السلسلة أو الحرف (مثل ";")، نوصيك باستخدام فئة StrinkTokenizer:

StringTokenizer

ولكن عندما يختلف الفاصل أو يكون معقدًا، نوصيك باستخدام التعبيرات العادية، والتي يمكن استخدامها بواسطة فئة السلسلة نفسها، وتقسيم الطريقة، منذ 1.4.ويستخدم فئة النمط من الحزمة java.util.regex

نمط

إذا كانت اللغة ميتة بسيطة مثل فقط

فعل اسم

ثم التقسيم باليد يعمل بشكل جيد.

إذا كان الأمر أكثر تعقيدًا، فيجب عليك البحث في أداة مثل ANTLR أو JavaCC.

لقد حصلت على برنامج تعليمي عن ANTLR (الإصدار 2) في http://javadude.com/articles/antlrtut والتي سوف تعطيك فكرة عن كيفية عمله.

JCommander يبدو جيدًا جدًا، على الرغم من أنني لم أختبره بعد.

إذا كان النص الخاص بك يحتوي على بعض المحددات، فيمكنك ذلك split طريقة.
إذا كان النص يحتوي على سلاسل غير منتظمة مما يعني تنسيقًا مختلفًا فيه، فيجب عليك استخدامه regular expressions.

يمكن لطريقة التقسيم تقسيم سلسلة إلى مصفوفة من تعبير السلسلة الفرعية المحدد regex.وحججه على شكلين، وهما:ينقسم (String regex) والتقسيم (String regex, int limit)، الذي انقسم (String regex) يتم في الواقع عن طريق استدعاء الانقسام (String regex، int Limit) لتحقيقه، الحد هو 0.ثم، عندما الحد> 0 و الحد <0 يمثل ماذا؟

عندما jdk شرح:متى الحد> 0 أطوال مجموعة فرعية تصل إلى الحد الأقصى، وهذا هو، إذا كان ذلك ممكنا، يمكن أن يكون الحد-1 قسم فرعي، يبقى كسلسلة فرعية (باستثناء حد 1 مرة يكون للحرف نهاية منقسمة للسلسلة)؛

الحد <0 يشير إلى عدم وجود حد لطول المصفوفة؛

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

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