كيفية الهروب من النص للتعبير العادي في جافا

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

  •  09-06-2019
  •  | 
  •  

سؤال

هل تحتوي Java على طريقة مضمنة للهروب من النص التعسفي بحيث يمكن تضمينه في التعبير العادي؟على سبيل المثال، إذا أدخل المستخدمون "$5"، فأنا أرغب في مطابقة ذلك تمامًا بدلاً من "5" بعد نهاية الإدخال.

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

المحلول

منذ جافا 1.5، نعم:

Pattern.quote("$5");

نصائح أخرى

الفرق بين Pattern.quote و Matcher.quoteReplacement لم يكن واضحا بالنسبة لي قبل أن أرى المثال التالي

s.replaceFirst(Pattern.quote("text to replace"), 
               Matcher.quoteReplacement("replacement text"));

قد يكون الوقت قد فات للرد، ولكن يمكنك أيضًا استخدامه Pattern.LITERAL, ، والذي سيتجاهل كافة الأحرف الخاصة أثناء التنسيق:

Pattern.compile(textToFormat, Pattern.LITERAL);

أعتقد أن ما تبحث عنه هو \Q$5\E.انظر أيضا Pattern.quote(s) قدم في Java5.

يرى نمط جافادوك للحصول على التفاصيل.

أولا، إذا

  • تستخدم استبدال الكل ()
  • لا تستخدم Matcher.quoteReplacement()
  • يتضمن النص الذي سيتم استبداله $1

لن يضع 1 في النهاية.سوف ينظر إلى التعبير العادي للبحث عن المجموعة المطابقة الأولى والفرعية الموجودة فيها.هذا ما يعنيه $1 أو $2 أو $3 في النص البديل:مطابقة المجموعات من نمط البحث.

كثيرًا ما أقوم بتوصيل سلاسل طويلة من النص إلى ملفات ‎.properties، ثم أقوم بإنشاء موضوعات ونصوص البريد الإلكتروني منها.في الواقع، يبدو أن هذه هي الطريقة الافتراضية للقيام بـ i18n في Spring Framework.أضع علامات XML، كعناصر نائبة، في السلاسل وأستخدم ReplaceAll() لاستبدال علامات XML بالقيم في وقت التشغيل.

لقد واجهت مشكلة حيث يقوم المستخدم بإدخال رقم الدولار والسنت، مع علامة الدولار.اختنق استبدال الكل () عليه، مع ظهور ما يلي في تتبع المسار:

java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)

في هذه الحالة، قام المستخدم بإدخال "$3" في مكان ما في مدخلاته، ثم ذهب استبدال الكل () للبحث في التعبير العادي للبحث عن المجموعة المطابقة الثالثة، ولم يعثر على واحدة، وتقيأ.

منح:

// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input

استبدال

msg = msg.replaceAll("<userInput \\/>", userInput);

مع

msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));

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

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

public class Test {
    public static void main(String[] args) {
        String str = "y z (111)";
        String p1 = "x x (111)";
        String p2 = ".* .* \\(111\\)";

        p1 = escapeRE(p1);

        p1 = p1.replace("x", ".*");

        System.out.println( p1 + "-->" + str.matches(p1) ); 
            //.*\ .*\ \(111\)-->true
        System.out.println( p2 + "-->" + str.matches(p2) ); 
            //.* .* \(111\)-->true
    }

    public static String escapeRE(String str) {
        //Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
        //return escaper.matcher(str).replaceAll("\\\\$1");
        return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
    }
}

Pattern.quote("blabla") يعمل بشكل جيد.

يعمل Pattern.quote() بشكل جيد.ويرفق الجملة بالأحرف "" و "\E"، وإذا تم الهروب من "\Q" و"\E".ومع ذلك، إذا كنت بحاجة إلى تنفيذ هروب تعبير عادي حقيقي (أو هروب مخصص)، فيمكنك استخدام هذا الرمز:

String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));

ترجع هذه الطريقة: بعض/\s/wText*/\,**

الكود على سبيل المثال والاختبارات:

String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));

يتم استخدام رمز ^(النفي) لمطابقة شيء غير موجود في مجموعة الأحرف.

هذا هو الرابط ل التعبيرات العادية

وهذه معلومات بالصورة عن النفي:

Info about negation

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