سؤال

أنا أستخدم Java Regexes في Java 1.6 (في جملة أمور منها تحليل الإخراج الرقمي) ولا يمكن العثور على تعريف دقيق لل \b ("حدود كلمة"). كنت قد افترضت ذلك -12 سيكون "كلمة عدد صحيح" (مطابقة \b\-?\d+\b) ولكن يبدو أن هذا لا يعمل. سأكون ممتنا بمعرفة طرق مطابقة الأرقام المنفصلة الفضاء.

مثال:

Pattern pattern = Pattern.compile("\\s*\\b\\-?\\d+\\s*");
String plus = " 12 ";
System.out.println(""+pattern.matcher(plus).matches());
String minus = " -12 ";
System.out.println(""+pattern.matcher(minus).matches());
pattern = Pattern.compile("\\s*\\-?\\d+\\s*");
System.out.println(""+pattern.matcher(minus).matches());

هذه المرتجعات:

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

المحلول

حدود كلمة، في معظم اللهجات Regex، هي موضع بين \w و \W (غير الكلمة سحر)، أو في بداية أو نهاية سلسلة إذا بدأ أو ينتهي (على التوالي) مع حرف كلمة ([0-9A-Za-z_]).

لذلك، في السلسلة "-12", ، سيتطابق قبل 1 أو بعد 2. اندفاعة ليست حرف كلمة.

نصائح أخرى

يمكن أن تحدث حدود كلمة في واحدة من ثلاث مواقع:

  1. قبل الحرف الأول في السلسلة، إذا كانت الشخصية الأولى هي حرف كلمة.
  2. بعد الحرف الأخير في السلسلة، إذا كانت الشخصية الأخيرة حرف كلمة.
  3. بين حرفين في السلسلة، حيث يتم احتساب حرف واحد والآخر ليس حرفا.

كلمة الشخصيات هي ألفا الرقمية؛ علامة ناقص ليست كذلك. مأخوذ من Regex التعليمي.

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

أنا أتحدث عن ما \bحدود regex -Style في الواقع هنا.

القصة القصيرة هي أنهم الشرط. وبعد سلوكهم يعتمد على ما هم بجانبهم.

# same as using a \b before:
(?(?=\w) (?<!\w)  | (?<!\W) )

# same as using a \b after:
(?(?<=\w) (?!\w)  | (?!\W)  )

في بعض الأحيان هذا ليس ما تريد. انظر إجابتي الأخرى للتوضيح.

تحقق من الوثائق حول ظروف الحدود:

http://java.sun.com/docs/books/tutorial/esental/regex/bounds.html.html.

تحقق من هذه العينة:

public static void main(final String[] args)
    {
        String x = "I found the value -12 in my string.";
        System.err.println(Arrays.toString(x.split("\\b-?\\d+\\b")));
    }

عند طباعةها، لاحظ أن الإخراج هو هذا:

وجدت القيمة - في سلسلة بلدي.

هذا يعني أن حرف "-" لا يتم التقاطه على أنه على حدود كلمة لأنه لا يعتبر حرفا كلمة. يبدو وكأنه Bebanary كيندا ضربني لكمة، لذلك يحصل على تصويت.

ركضت مشكلة أسوأ عند البحث عن نص للكلمات .NET, C++, C#, ، و C. وبعد كنت تعتقد أن مبرمجي الكمبيوتر يعرفون أفضل من تسمية لغة من الصعب كتابة تعبيرات منتظمة ل.

على أي حال، هذا ما اكتشفته (موجز في الغالب من http://www.regular-Expressions.info., ، وهو موقع رائع): في معظم نكهات Regex، الشخصيات التي تتم مطابقتها فئة الأحرف قصيرة اليد القصيرة \w هي الأحرف التي تعامل كحرف كلمة من حدود الكلمات. جافا استثناء. جافا يدعم Unicode for \b ولكن ليس ل \w. وبعد (أنا متأكد من أن هناك سبب وجيه لذلك في ذلك الوقت).

ال \w يقف ل "شخصية كلمة". دائما يطابق أحرف ASCII [A-Za-z0-9_]. وبعد لاحظ إدراج السفل والأرقام (ولكن ليس اندفاعة!). في معظم النكهات التي تدعم Unicode، \w يتضمن العديد من الأحرف من البرامج النصية الأخرى. هناك الكثير من التناقضات حول الأحرف التي يتم تضمينها بالفعل. يتم تضمين رسائل وأرقام من البرامج النصية الأبجدية والأيديوشروج. رموز علامات الترقيم بخلاف الرموز السفلية والرقمية التي لا تكون أرقاما قد تكون أو لا تكون مضمنة. تشمل مخطط XML و XPath حتى جميع الرموز في \w. وبعد ولكن Java، JavaScript، ومطابقة PCRE فقط أحرف ASCII مع \w.

وهذا هو السبب في عمليات البحث Regex القائمة على Java C++, C# أو .NET (حتى عندما تتذكر أن تفلت الهروب من الفترة والإلغاء) \b.

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

على أي حال، في Java، إذا كنت تبحث عن نص لتلك اللغات التي تسمى الغريب، تحتاج إلى استبدال \b مع قبل وبعد مستويات البيضاء ومضمون علامات الترقيم. علي سبيل المثال:

public static String grep(String regexp, String multiLineStringToSearch) {
    String result = "";
    String[] lines = multiLineStringToSearch.split("\\n");
    Pattern pattern = Pattern.compile(regexp);
    for (String line : lines) {
        Matcher matcher = pattern.matcher(line);
        if (matcher.find()) {
            result = result + "\n" + line;
        }
    }
    return result.trim();
}

ثم في الاختبار أو الوظيفة الرئيسية:

    String beforeWord = "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|^)";   
    String afterWord =  "(\\s|\\.|\\,|\\!|\\?|\\(|\\)|\\'|\\\"|$)";
    text = "Programming in C, (C++) C#, Java, and .NET.";
    System.out.println("text="+text);
    // Here is where Java word boundaries do not work correctly on "cutesy" computer language names.  
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for .NET="+ grep("\\b\\.NET\\b", text));
    System.out.println("Should find: grep exactly for .NET="+ grep(beforeWord+"\\.NET"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java: grep with word boundary for C#="+ grep("\\bC#\\b", text));
    System.out.println("Should find: grep exactly for C#="+ grep("C#"+afterWord, text));
    System.out.println("Bad word boundary can't find because of Java:grep with word boundary for C++="+ grep("\\bC\\+\\+\\b", text));
    System.out.println("Should find: grep exactly for C++="+ grep(beforeWord+"C\\+\\+"+afterWord, text));

    System.out.println("Should find: grep with word boundary for Java="+ grep("\\bJava\\b", text));
    System.out.println("Should find: grep for case-insensitive java="+ grep("?i)\\bjava\\b", text));
    System.out.println("Should find: grep with word boundary for C="+ grep("\\bC\\b", text));  // Works Ok for this example, but see below
    // Because of the stupid too-short cutsey name, searches find stuff it shouldn't.
    text = "Worked on C&O (Chesapeake and Ohio) Canal when I was younger; more recently developed in Lisp.";
    System.out.println("text="+text);
    System.out.println("Bad word boundary because of C name: grep with word boundary for C="+ grep("\\bC\\b", text));
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));
    // Make sure the first and last cases work OK.

    text = "C is a language that should have been named differently.";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    text = "One language that should have been named differently is C";
    System.out.println("text="+text);
    System.out.println("grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

    //Make sure we don't get false positives
    text = "The letter 'c' can be hard as in Cat, or soft as in Cindy. Computer languages should not require disambiguation (e.g. Ruby, Python vs. Fortran, Hadoop)";
    System.out.println("text="+text);
    System.out.println("Should be blank: grep exactly for C="+ grep(beforeWord+"C"+afterWord, text));

ملاحظة بلدي الشكر http://regexpal.com/ بدون من هو العالم ريجيكس سيكون بائسة جدا!

في سياق تعلم التعبير العادي، كنت عالقا حقا في metacharacter وهو \b. وبعد حقا لم يفهم معناها بينما كنت أسأل نفسي "ما هو عليه، ما هو عليه"بشكل متكرر. بعد بعض المحاولات باستخدام الموقع, ، أشاهد الشرط العمودي الوردي في كل بداية للكلمات وفي نهاية الكلمات. حصلت عليه معنى لها في ذلك الوقت. انها الآن بالضبط كلمة(\w) -.

رأيي هو مجرد التفاهم الشديد. المنطق وراءه يجب فحصه من إجابات أخرى.

enter image description here

أود أن أشرح آلان مورإجابة

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

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

لذلك سوف أدفع ريجيكس (في بيثون) كما

re.sub("\ba","e", myString.strip()) //يستبدل a مع e

لذلك سيكون الإخراج هذا هو e جيمأب eو هي eرعب

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

بديل واحد ممكن هو

(?:(?:^|\s)-?)\d+\b

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

يستخدم حدود الحدود B حيث يجب أن تكون كلمة واحدة حرفا واحدا آخر حرفا غير الكلمات. يجب أن يكون التعبير العادي للعدد السالب

--?\b\d+\b

تحقق من العمل التجريبي

أعتقد أنها الحدود (أي شخصية متابعة) للمباراة الأخيرة أو بداية أو نهاية السلسلة.

عند استخدامها \\b(\\w+)+\\b وهذا يعني التطابق الدقيق بكلمة تحتوي على أحرف كلمة فقط ([a-zA-Z0-9])

في حالتك على سبيل المثال \\b في بداية Regex سوف تقبل -12(مع الفضاء) ولكن مرة أخرى لن يقبل -12(بدون مساحة)

للرجوع اليها لدعم كلماتي: https:/docs.oracle.com/javase/tutorial/essental/regex/bounds.html.

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