그것은 나의 이해입니다 java.regex
패키지라는 이름의 그룹 (에 대한 지원이없는 http://www.regular-expressions.info/named.html 않는 타사 라이브러리를 향해 캔 누구 포인트 나 정도)?
jregex를 살펴 보았지만 마지막 릴리스는 2002 년이며 java5에서는 저에게 효과적이지 않았습니다 (간단히 시도했습니다).
답변
( 업데이트 : 2011 년 8 월 )
으로 geofflane가 에 언급 그의 대답 , 자바 7은 현재라는 이름의 그룹을 지원 .
tchrist 는 의견에서 지원이 제한적이라고 지적합니다.
그는 훌륭한 답변 ” Java Regex Helper ” 의 제한 사항에 대해 자세히 설명합니다.
Java 7 정규식 그룹 지원은 2010 년 9 월 Oracle 블로그에서 다시 발표되었습니다 .
Java 7의 공식 릴리스에서 명명 된 캡처 그룹을 지원하는 구성은 다음과 같습니다.
(?<name>capturing text)
명명 된 그룹 “name”을 정의\k<name>
명명 된 그룹 “name”을 역 참조하는 방법${name}
Matcher의 대체 문자열에서 캡처 된 그룹을 참조Matcher.group(String name)
지정된 “명명 된 그룹”에 의해 캡처 된 입력 서브 시퀀스를 리턴합니다.
Java 7 이전의 다른 대안 은 다음과 같습니다.
- 구글 명명 정규식 ( John Hardy 의 답변 참조 )
Gábor Lipták 은이 프로젝트가 활성 상태가 아닐 수 있으며 ( 몇 가지 눈에 띄는 버그가 있음 ) GitHub 포크 가 대신 고려 될 수 있다고 언급했습니다 (2012 년 11 월) . - jregex ( Brian Clozel 의 답변 참조 )
( 원래 답변 : 2009 년 1 월 , 다음 두 링크가 끊어짐)
자신의 Regex 버전을 코딩하지 않으면 명명 된 그룹을 참조 할 수 없습니다.
그것이 바로이 스레드에서 Gorbush2가 한 일입니다 .
ASCII 식별자 만 찾기 때문에 tchrist가 다시 지적한 제한적인 구현 . tchrist는 다음과 같은 제한 사항을 자세히 설명합니다.
같은 이름마다 하나의 명명 된 그룹 만 가질 수 있으며 (항상 제어 할 수있는 것은 아닙니다!) 정규식 재귀에 사용할 수 없습니다.
참고 : Regexp Power , PCRE 사양 및 균형 괄호가있는 일치 문자열에 언급 된 것처럼 Perl 및 PCRE 정규 표현식에서 실제 정규식 재귀 예제를 찾을 수 있습니다 )
예:
끈:
"TEST 123"
정규식 :
"(?<login>\\w+) (?<id>\\d+)"
접속하다
matcher.group(1) ==> TEST
matcher.group("login") ==> TEST
matcher.name(1) ==> login
바꾸다
matcher.replaceAll("aaaaa_$1_sssss_$2____") ==> aaaaa_TEST_sssss_123____
matcher.replaceAll("aaaaa_${login}_sssss_${id}____") ==> aaaaa_TEST_sssss_123____
(구현에서 추출)
public final class Pattern
implements java.io.Serializable
{
[...]
/**
* Parses a group and returns the head node of a set of nodes that process
* the group. Sometimes a double return system is used where the tail is
* returned in root.
*/
private Node group0() {
boolean capturingGroup = false;
Node head = null;
Node tail = null;
int save = flags;
root = null;
int ch = next();
if (ch == '?') {
ch = skip();
switch (ch) {
case '<': // (?<xxx) look behind or group name
ch = read();
int start = cursor;
[...]
// test forGroupName
int startChar = ch;
while(ASCII.isWord(ch) && ch != '>') ch=read();
if(ch == '>'){
// valid group name
int len = cursor-start;
int[] newtemp = new int[2*(len) + 2];
//System.arraycopy(temp, start, newtemp, 0, len);
StringBuilder name = new StringBuilder();
for(int i = start; i< cursor; i++){
name.append((char)temp[i-1]);
}
// create Named group
head = createGroup(false);
((GroupTail)root).name = name.toString();
capturingGroup = true;
tail = root;
head.next = expr(tail);
break;
}
답변
늦게 오는 사람들을 위해 : Java 7은 명명 된 그룹을 추가합니다. Matcher.group (String groupName) 설명서
답변
그렇습니다.하지만 태양 클래스를 해킹하는 것은 지저분합니다. 더 간단한 방법이 있습니다.
http://code.google.com/p/named-regexp/
named-regexp는 표준 JDK 정규 표현식 구현을위한 씬 래퍼이며 .net 스타일에서 명명 된 캡처 그룹을 처리하는 단일 목적은 (? …)입니다.
Java 5 및 6과 함께 사용할 수 있습니다 (일반이 사용됨).
Java 7은 명명 된 캡처 그룹을 처리하므로이 프로젝트는 지속되지 않습니다.
답변
jregex 어떤 종류의 문제가 있습니까? java5 및 java6에서 저에게 효과적이었습니다.
javaSE 7을 기다리지 않는 한 Jregex는 (마지막 버전이 2002 버전이더라도) 잘 작동합니다 .
답변
java7 이전 버전을 실행하는 사용자의 경우 이름 지정된 그룹은 joni ( Oniguruma regexp 라이브러리 의 Java 포트)에서 지원됩니다 . 문서는 드물지만 우리에게는 잘 작동했습니다.
바이너리는 Maven ( http://repository.codehaus.org/org/jruby/joni/joni/ )을 통해 사용할 수 있습니다 .
답변
조금 오래된 질문이지만 나는 이것을 필요로하고 위의 제안이 부적절하다는 것을 알았습니다. 따라서 얇은 포장지가 직접 개발되었습니다 : https://github.com/hofmeister/MatchIt