sourcecode

Java에서 대소문자를 구분하지 않는 리터럴 서브스트링을 교체하는 방법

copyscript 2022. 9. 17. 09:52
반응형

Java에서 대소문자를 구분하지 않는 리터럴 서브스트링을 교체하는 방법

사용방법replace(CharSequence target, CharSequence replacement)String에서 타겟을 대소문자를 구분하지 않도록 하려면 어떻게 해야 합니까?

예를 들어, 현재 작동 방식:

String target = "FooBar";
target.replace("Foo", "") // would return "Bar"

String target = "fooBar";
target.replace("Foo", "") // would return "fooBar"

대체(또는 더 적합한 방법이 있는 경우)를 대소문자를 구분하지 않고 두 예에서 모두 "막대"를 반환하도록 하려면 어떻게 해야 합니까?

String target = "FOOBar";
target = target.replaceAll("(?i)foo", "");
System.out.println(target);

출력:

Bar

을 언급할 가치가 있다replaceAll그럼 첫 번째 인수가 regex 패턴으로 처리되므로 예기치 않은 결과가 발생할 수 있습니다.이를 해결하려면 댓글에 제시된 대로 사용하세요.

케이스에 관심이 없다면 모든 업케이스가 반환되어도 상관없습니다.

target.toUpperCase().replace("FOO", "");

정규 표현은 다음과 같은 일부 문자가 예약되어 있기 때문에 관리가 매우 복잡합니다."foo.bar".replaceAll(".")점이 "임의"를 의미하기 때문에 빈 문자열을 생성합니다. 바꾸려면 점만 매개 변수로 지정해야 합니다."\\.".

보다 간단한 해결책은 StringBuilder 개체를 사용하여 텍스트를 검색하고 바꾸는 것입니다.두 가지 방법이 있습니다. 하나는 소문자로 된 텍스트를 포함하고 두 번째는 원본 버전을 포함합니다.검색은 소문자 콘텐츠에서 수행되며 검색된 인덱스가 원본 텍스트도 대체합니다.

public class LowerCaseReplace 
{
    public static String replace(String source, String target, String replacement)
    {
        StringBuilder sbSource = new StringBuilder(source);
        StringBuilder sbSourceLower = new StringBuilder(source.toLowerCase());
        String searchString = target.toLowerCase();

        int idx = 0;
        while((idx = sbSourceLower.indexOf(searchString, idx)) != -1) {
            sbSource.replace(idx, idx + searchString.length(), replacement);
            sbSourceLower.replace(idx, idx + searchString.length(), replacement);
            idx+= replacement.length();
        }
        sbSourceLower.setLength(0);
        sbSourceLower.trimToSize();
        sbSourceLower = null;

        return sbSource.toString();
    }


    public static void main(String[] args)
    {
        System.out.println(replace("xXXxyyyXxxuuuuoooo", "xx", "**"));
        System.out.println(replace("FOoBaR", "bar", "*"));
    }
}

아마도 다른 접근법만큼 우아하지는 않지만, 꽤 견고하고 따라하기 쉬우며, 특히 Java에 익숙하지 않은 사람들에게는 그렇습니다.String 클래스에서 얻을 수 있는 것은 다음과 같습니다.이는 매우 오랫동안 존재해 왔으며 regexp에 의한 글로벌 치환 및 Char Sequences에 의한 Strings에 의한 글로벌 치환을 지원하지만 마지막으로 단순한 부울 파라미터 'isCase'가 없습니다.무신경하다.정말로, 그 작은 스위치를 하나 추가하는 것만으로, 특히 초심자에게 있어서 발생하는 번거로움을 피할 수 있다고 생각했을 것입니다.JDK 7에서도 String은 이 작은 추가 기능을 지원하지 않습니다.

어쨌든 불평은 그만할게요.특히 Java를 처음 접하는 모든 사람들을 위해, 여기 잘라낸 페이스트 데우스 ex Machina가 있습니다.말씀드렸듯이, 우아하지도 않고, 매끄러운 코드 상도 받을 수 없지만, 효과가 있고 신뢰할 수 있습니다.어떤 의견이든 자유롭게 기고해 주세요.(네, String Buffer가 2개의 문자열 변환 행을 관리하는 데 더 좋은 선택이라는 것을 알고 있습니다만, 이러한 기술을 충분히 교환할 수 있습니다.)

public String replaceAll(String findtxt, String replacetxt, String str, 
        boolean isCaseInsensitive) {
    if (str == null) {
        return null;
    }
    if (findtxt == null || findtxt.length() == 0) {
        return str;
    }
    if (findtxt.length() > str.length()) {
        return str;
    }
    int counter = 0;
    String thesubstr = "";
    while ((counter < str.length()) 
            && (str.substring(counter).length() >= findtxt.length())) {
        thesubstr = str.substring(counter, counter + findtxt.length());
        if (isCaseInsensitive) {
            if (thesubstr.equalsIgnoreCase(findtxt)) {
                str = str.substring(0, counter) + replacetxt 
                    + str.substring(counter + findtxt.length());
                // Failing to increment counter by replacetxt.length() leaves you open
                // to an infinite-replacement loop scenario: Go to replace "a" with "aa" but
                // increment counter by only 1 and you'll be replacing 'a's forever.
                counter += replacetxt.length();
            } else {
                counter++; // No match so move on to the next character from
                           // which to check for a findtxt string match.
            }
        } else {
            if (thesubstr.equals(findtxt)) {
                str = str.substring(0, counter) + replacetxt 
                    + str.substring(counter + findtxt.length());
                counter += replacetxt.length();
            } else {
                counter++;
            }
        }
    }
    return str;
}

서드파티 라이브러리가 없어도 간단하게 할 수 있습니다.

    final String source = "FooBar";
    final String target = "Foo";
    final String replacement = "";
    final String result = Pattern.compile(target, Pattern.LITERAL | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(source)
.replaceAll(Matcher.quoteReplacement(replacement));

유니코드 이외의 문자의 경우:

String result = Pattern.compile("(?i)препарат", 
Pattern.UNICODE_CASE).matcher(source).replaceAll("БАД");

org.disc.disc.disc.discString Utils:

public static String replace Ignore Case(문자열 텍스트, 문자열 검색 문자열, 문자열 치환)

대소문자는 다른 문자열 내의 모든 문자열을 무심코 대체합니다.

나는 스마스대답이 마음에 든다replaceAll을 여러 번 을 한 번 미리 이 좋습니다.같은 치환을 여러 번 실행하는 경우 정규 표현을 한 번 미리 컴파일하는 것이 좋습니다.

import java.util.regex.Pattern;

public class Test { 

    private static final Pattern fooPattern = Pattern.compile("(?i)foo");

    private static removeFoo(s){
        if (s != null) s = fooPattern.matcher(s).replaceAll("");
        return s;
    }

    public static void main(String[] args) {
        System.out.println(removeFoo("FOOBar"));
    }
}
String newstring  = "";
String target2 = "fooBar";
newstring = target2.substring("foo".length()).trim();   
logger.debug("target2: {}",newstring); 
// output: target2: Bar
    
String target3 = "FooBar";
newstring = target3.substring("foo".length()).trim();
logger.debug("target3: {}",newstring); 
// output: target3: Bar

언급URL : https://stackoverflow.com/questions/5054995/how-to-replace-case-insensitive-literal-substrings-in-java

반응형