2017-04-05 4 views
1

""로 시작하고 "["(이전에 계속되는하지만 반드시 그 옆에있는 것은 아니지만) 다음에 오는 경우에만 하위 문자열의 모든 항목을 바꿔야합니다 부분 문자열). 예 : 대체 할 수있는 표현이 있었다면일부 문자로 구분 된 텍스트의 특정 부분에만 하위 문자열 바꾸기

[style and tags info] valid text info [more style info] more info here[styles] 

:

이 내가 대체 할 필요가 문자열 될 정보는 -> 변경

(이것은 하나의 단어보다 더있을 수 있습니다)

결과는 같아야합니다

[style and tags info] valid text change [more style info] more change here [styles] 

내 생각은 내가 변경 한 다음 완전히 대체하기에 호출을 교체 할 필요가 단어를 분리하는 정규식을 사용하는 것이 었습니다.

하지만 성공적이지 않은 검색 식을 분리하기 위해 몇 가지 정규식을 시도했습니다. 주로 내가 뭔가를 필요로하기 때문에

(?<=.*) 

이것은 내가 찾고있는 단어 앞에 임의의 수의 문자로 보이는 것입니다. 그리고 이것은 자바 정규식 (그리고 내가 아는 regex의 다른 구현물)에 의해 지원되지 않습니다.

내가 MATLAB에 기록이 솔루션을 발견하지만, 자바에서 복제 어려워 보인다 : 간단한 접근 방법은

Matlab regex - replace substring ONLY within angled brackets

있습니까? 내가 고려하지 않은 일부 정규식?

+0

'[...]'밖에서 만'change'를 바꾸지 않는 이유는 무엇입니까? 제 말은,'info'가 첫 번째'[...]'앞에 있다면, 대체되어서는 안되는 것입니까? –

답변

1

일치 건너 :

예를 들어, 당신이 사용하는 분할을 수행 할 수 있습니다 (이것은 당신의 []의이 두 [[ 등을 개방하지 않을 고르게 균형있는 것으로 가정) [으로 시작하는 하위 문자열은 [] 이외의 하나 이상의 문자를 가지고 있으며 ]까지이며 infochange으로 바꿉니다.

String s = "[style and tags info] valid text info [more style info] more info here[styles]"; 
StringBuffer result = new StringBuffer(); 
Matcher m = Pattern.compile("\\[[^\\]\\[]+]|\\b(info)\\b").matcher(s); 
while (m.find()) { 
    if (m.group(1) != null) { 
     m.appendReplacement(result, "change"); 
    } 
    else { 
     m.appendReplacement(result, m.group()); 
    } 
} 
m.appendTail(result); 
System.out.println(result.toString()); 
// => [style and tags info] valid text change [more style info] more change here[styles] 

Java demo

\[[^\]\[]+]|\b(info)\b 정규식 \[[^\]\[]+] 다른 지점과 \b(info)\b 지점 (그룹 1)와 그 [...] 문자열 일치를 참조하십시오 전체 단어 info을 캡처 :이를 위해, 당신은 Matcher#appendReplacement() 방법을 사용할 수 있습니다. 그룹 1이 일치하면 대체가 발생하고 일치하지 않으면 일치하는 [...] 하위 문자열이 결과에 다시 삽입됩니다. 당신의 원래 로직으로

는, 그래, 당신은 ($1change 교체 포함) (?:\G|(?<=]))([^\]\[]*?)\binfo\b 정규식 .replaceAll는 "간단한"를 사용할 수 있습니다,하지만 난 당신이 필요 의심.

+1

흠 잡을 데없이 일했습니다! 심지어 텍스트의 일부 자리에 대괄호가 일치하지 않아도됩니다. 고마워. –

3

여기서 가장 쉬운 방법은 문자열을 괄호 안의 부분과 괄호 안의 부분으로 나눈 다음 대괄호 안의 부분 만 바꾸는 것입니다. 그것은 더 적절한 것 같다

String[] parts = str.split("[\[\]]"); 
StringBuilder sb = new StringBuilder(str.length()); 
for (int i = 0; i < parts.length; i++) { 
    if (i % 2 == 0) { 
    // This bit was outside []. 
    sb.append(parts[i]); 
    } else { 
    // This bit was inside [], so apply the replacement 
    // (and re-append the delimiters). 
    sb.append("["); 
    sb.append(parts[i].replace("info", "change")); 
    sb.append("]"); 
    } 
} 
String newStr = sb.toString();