2009-12-16 5 views
0

Ok ... 문제에 대한 만족스럽지 못한 해결책이 있습니다.변수 수를 바꾸는 ... 정규식?

{sup 19}F({sup 3}He,t){sup 19}Ne(p){sup 18}F 

등등과 같은 출력을 필요 :

¹⁹F(³He,t)¹⁹Ne(p)¹⁸F 

를 I 먼저 {SUP의 XX}의 각 섹션을 분할 교체 일련 사용

문제는 그 입력과 같이있을 것이다 {sup x} {sup x}로 변환 한 다음 각각의 정규 표현식을 사용하여 문자를 UTF-8 단일 대체 문자로 바꿉니다. "문제"는 {sup} 섹션이 1, 2 또는 3 자릿수의 길이를 가질 수 있다는 것입니다 (어쩌면 더 많은 것을 알 수 있습니다). 각 섹션을 하나의 숫자로 분리 된 {sup} 섹션으로 "확장"하고자합니다. .

retval = retval.replaceAll("\\{sup ([1-9])([0-9])\\}", "{sup $1}{sup $2}"); 
retval = retval.replaceAll("\\{sup ([1-9])([0-9])([0-9])\\}", "{sup $1}{sup $2}{sup $3}"); 

내 질문 :이 작업을 수행 할 수있는 방법이

나의 현재 솔루션 (자바)과 같다 (나는 또한 ... 첨자 {하위}과 같은 문제가 있습니다) 얼마나 많은 숫자 (또는 적어도 적당한 숫자)가 있더라도 하나의 패스?

답변

3

예, 그렇지만 해킹 비트 일 수 있으므로주의해야합니다. 오버플로!

정규식 :

(?:\{sup\s)?(\d)(?=\d*})}? 

교체 문자열 :

{sup $1} 

짧은 설명 : 일반 영어

(?:       | start non-capturing group 1 
    \{       | match the character '{' 
    sup       | match the substring: "sup" 
    \s       | match any white space character 
)        | end non-capturing group 1 
?        | ...and repeat it once or not at all 
(        | start group 1 
    \d       | match any character in the range 0..9 
)        | end group 1 
(?=       | start positive look ahead 
    \d       | match any character in the range 0..9 
    *       | ...and repeat it zero or more times 
    }       | match the substring: "}" 
)        | stop negative look ahead 
}        | match the substring: "}" 
?        | ...and repeat it once or not at all 

: 그것은 하나의 숫자와 일치를 찾고 때만이 앞서있다 } 사이에 임의의 숫자가 있습니다. 가능한 경우 하위 문자열 {sup}도 대체됩니다.

편집 :

더 나은 하나가 이것이다 :

(?:\{sup\s|\G)(\d)(?=\d*})}? 

그 방법, 문자열 "set={123}"에 같은 숫자가 교체되지 않습니다. 내 두 번째 정규식에있는 \G은 이전 경기가 끝난 지점과 일치합니다.

+0

왜'{sup '부분을 선택 사항으로 표시 했습니까? '1}'과 (과) 일치하는 것 같습니다. –

+0

@Mike : OP는'{sup 123}'을'{sup 1} {sup 2} {sup 3}'로 대체하려고합니다. 첫 번째 자릿수 앞에'{sup}가 있고 그 뒤에 마지막 자릿수에는'}'이 있습니다. 그 이유는 선택 사항입니다. –

+0

@Mike : 아, 무슨 뜻인지 알 겠어. 따라서 내 발언은 "너는 조심해야한다 * overmatch *!". 저의 두 번째 해결책 인'\ G'가 들어있는 것을보십시오. –

0

물론 이것은 표준 정규 표현식 구성입니다. Pattern Javadoc에있는 모든 메타 문자에 대해 알 수 있지만, 목적에 따라 "+"메타 문자 또는 {1,3} 욕심 많은 수량 한정 기호를 원할 수도 있습니다. 링크의 세부 정보.

+0

아니요, 오해했습니다. OP가 하나 이상의 숫자와 일치하는 방법을 찾지 못했습니다. –

1

이런 종류의 작업을 수행하는 가장 쉬운 방법은 PHP의 preg_replace_callback 또는 .NET의 MatchEvaluator 대리자를 사용하는 것입니다. Java에는 내장 된 것과 같은 것이 없지만 직접 구현할 수있는 하위 수준의 API가 제공됩니다.

import java.util.regex.*; 

public class Test 
{ 
    static String sepsup(String orig) 
    { 
    Pattern p = Pattern.compile("(\\{su[bp])(\\d+)\\}"); 
    Matcher m = p.matcher(orig); 
    StringBuffer sb = new StringBuffer(); 
    while (m.find()) 
    { 
     m.appendReplacement(sb, ""); 
     for (char ch : m.group(2).toCharArray()) 
     { 
     sb.append(m.group(1)).append(ch).append("}"); 
     } 
    } 
    m.appendTail(sb); 
    return sb.toString(); 
    } 

    public static void main (String[] args) 
    { 
    String s = "{sup 19}F({sup 3}He,t){sub 19}Ne(p){sup 18}F"; 
    System.out.println(s); 
    System.out.println(sepsup(s)); 
    } 
} 

결과 : 당신이 원하는 경우

{sup 19}F({sup 3}He,t){sub 19}Ne(p){sup 18}F 
{sup 1}{sup 9}F({sup 3}He,t){sub 1}{sub 9}Ne(p){sup 1}{sup 8}F 

, 당신이 가서 첨자 및 아래 첨자 문자를 생성하고 대신들을 삽입 할 수 여기 한 가지 방법이다.