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
'sourcecode' 카테고리의 다른 글
두 Joda-Time DateTimes 간의 차이를 분 단위로 찾는 방법 (0) | 2022.09.17 |
---|---|
속도 향상 인텔리J-Idea (0) | 2022.09.17 |
작업 작성자의 Redx 상태에 액세스하시겠습니까? (0) | 2022.09.17 |
MySQL "ERROR 1005 (HY000)" :'foo' 테이블을 만들 수 없습니다.#sql-12c_4' (오류번호: 150) (0) | 2022.09.17 |
Java 또는 C#에서의 예외 관리 베스트 프랙티스 (0) | 2022.09.17 |