Ich lief in einem noch schlimmeren Problem, wenn Text für Wörter wie .NET
Suche, C++
, C#
und C
. Sie würden denken, dass Computerprogrammierer es besser wissen würden, als eine Sprache zu benennen, für die es schwer ist, reguläre Ausdrücke zu schreiben.
Auf jeden Fall ist es das, was ich herausgefunden (zusammengefasst meist aus http://www.regular-expressions.info, das ist ein großer Standort ist): In den meisten Aromen von regex, Zeichen, die durch die Kurz Hand Zeichenklasse abgestimmt sind \w
sind die Zeichen, die als behandelt werden Wortzeichen nach Wortgrenzen. Java ist eine Ausnahme. Java unterstützt Unicode für \b
, aber nicht für \w
. (Ich bin mir sicher, dass es zu der Zeit einen guten Grund dafür gab).
Die \w
steht für "word character". Es entspricht immer den ASCII-Zeichen [A-Za-z0-9_]
. Beachten Sie die Angabe von Unterstrich und Ziffern (aber nicht Bindestrich!). In den meisten Varianten, die Unicode unterstützen, enthält \w
viele Zeichen aus anderen Skripts. Es gibt viele Unstimmigkeiten darüber, welche Zeichen tatsächlich enthalten sind. Buchstaben und Ziffern aus alphabetischen Schriften und Ideogrammen sind im Allgemeinen enthalten. Connector-Interpunktion mit Ausnahme des Unterstrichs und numerische Symbole, die keine Ziffern sind, können enthalten sein oder nicht. XML-Schema und XPath enthalten sogar alle Symbole in \w
. Aber Java, JavaScript und PCRE stimmen nur mit ASCII-Zeichen mit \w
überein.
Weswegen Java-basierte Regex sucht nach C++
, C#
oder .NET
(auch wenn Sie daran denken, die Zeit und Pluspunkte zu entkommen) durch die \b
verschraubt sind.
Hinweis: Ich bin mir nicht sicher, was ich bei Textfehlern tun soll, z. B. wenn jemand nach einer bestimmten Zeit am Ende eines Satzes keinen Platz eingibt. Ich habe es zugelassen, aber ich bin mir nicht sicher, ob es das Richtige ist.
Wie auch immer, in Java, wenn Sie Text für diese merkwürdig benannten Sprachen suchen, müssen Sie die \b
durch vor und nach Leerzeichen und Interpunktionsbezeichner ersetzen. Zum Beispiel:
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();
}
Dann in Ihrem Test oder Hauptfunktion:
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));
P. S. Mein Dank an http://regexpal.com/ ohne wen die Regex-Welt sehr miserabel wäre!
können Sie ein kleines Beispiel mit Eingang und Ausgang erwartet posten? –
Wird versuchen, einen zu konstruieren –
Beispiel \t Muster pattern = Pattern.compile ("\\ s * \\ b \\ -? \\ d + \\ s *"); \t Zeichenfolge plus = "12"; \t System.out.println ("" + pattern.matcher (plus) .matches()); \t String minus = "-12"; \t System.out.println ("" + pattern.matcher (minus) .matches()); \t pattern = Pattern.compile ("\\ s * \\ -? \\ d + \\ s *"); \t System.out.println ("" + pattern.matcher (minus) .matches()); gibt: true false true –