즉 원하는 텍스트를 검색 할 때 내가 더 악화 문제로 실행 .NET
, C++
, C#
, 및C
. 컴퓨터 프로그래머는 정규 표현식을 작성하기 어려운 언어의 이름을 지정하는 것보다 더 잘 알고 있다고 생각합니다.
어쨌든, 이것은 내가 찾은 것입니다 (대부분 훌륭한 사이트 인 http://www.regular-expressions.info 에서 요약 됩니다) : 대부분의 정규 표현식에서 짧은 문자 클래스와 일치하는 문자 \w
는 단어 경계에 의해 단어 문자로 취급되는 문자. Java는 예외입니다. Java는 유니 코드를 지원 \b
하지만 지원 하지는 않습니다 \w
. (당시에는 그만한 이유가 있다고 확신합니다).
는 \w
"단어 문자"를 의미합니다. 항상 ASCII 문자와 일치합니다 [A-Za-z0-9_]
. 밑줄과 숫자가 포함되어 있음을 주목하십시오 (단, 대시는 아님). 유니 코드를 지원 \w
하는 대부분의 특징에는 다른 스크립트의 많은 문자가 포함됩니다. 어떤 문자가 실제로 포함되는지에 대해 많은 불일치가 있습니다. 알파벳 문자 및 표의 문자와 숫자가 일반적으로 포함됩니다. 밑줄 및 숫자 이외의 숫자 기호 이외의 커넥터 문장 부호는 포함되거나 포함되지 않을 수 있습니다. XML Schema 및 XPath는의 모든 기호를 포함합니다 \w
. 그러나 Java, JavaScript 및 PCRE는 ASCII 문자 만와 일치합니다 \w
.
대한 정규식 검색을 자바 기반 이유는 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/에 감사합니다 !