문자열에서 모든 문자를 제거하십시오.


311

나는 이것을 사용할 수 있습니다 :

String str = "TextX Xto modifyX";
str = str.replace('X','');//that does not work because there is no such character ''

XJava의 String에서 모든 문자를 제거하는 방법이 있습니까?

나는 이것을 시도했지만 내가 원하는 것이 아니다. str.replace('X',' '); //replace with space


3
단일 문자 문자열을 바꾸려고 했습니까?
— peter.murray.rust

답변:


523

인수 대신 인수 (예 :)를CharSequence 사용하는 과부하를 사용해보십시오 .Stringchar

str = str.replace("X", "");

2
첫 번째 인수는 정규 표현식이며, 특히이 문자열이 사용자 입력에서 오는 경우 예상대로 작동하지 않을 수 있습니다.
— vbezhenar

9
@vsb : 사실이 아닙니다. 해당 특정 과부하의 두 가지 인수는 모두 CharSequence입니다. docs.oracle.com/javase/7/docs/api/java/lang/…
— LukeH

Xchar 유형 인 경우 어떻게해야합니까 ?
— KNU

7
@ Kunal : toString먼저 해야 할 것 같아요 . 따라서 코드는 다음과 같습니다str = str.replace(yourChar.toString(), "");
— LukeH

당신은 유니 코드 이스케이프, 예를 들어, 어떤 제거 noncharacters 사용할 수 있습니다str = str.replace("\uffff", "");
— 제이미 Hablutzel

42

사용

public String replaceAll(String regex, String replacement)

작동합니다.

사용법은입니다 str.replace("X", "");.

실행

"Xlakjsdf Xxx".replaceAll("X", "");

보고:

lakjsdf xx

6
Java 1.4 지원으로 제한되지 않는 한 정규식은 아마도 너무 과잉입니다. 1.5 버전부터 replace간단한 오버로드가 CharSequence있습니다.
— LukeH

3
@LukeH, String.replace로 디 컴파일 된 소스입니다. 정규식을 사용하고 있습니다. 나는 정규 표현식이 무겁다는 것에 동의하지만, 위의 받아 들인 대답조차도 후드 아래에 있습니다. public String replace (CharSequence var1, CharSequence var2) {return Pattern.compile (var1.toString (), 16) .matcher (this) .replaceAll (Matcher.quoteReplacement (var2.toString ())); }
— 페리는


6
String test = "09-09-2012";
String arr [] = test.split("-");
String ans = "";

for(String t : arr)
    ans+=t;

이것은 문자열에서 문자를 제거 한 예입니다.


4
이것은 특히 허용되는 답변과 비교할 때 매우 비효율적입니다.
— Erick Robertson

3
이 답변은 효과가 있다고 생각하지만 정답은 더 짧고 빠릅니다
— evilReiko

2

이 경우 RegEx를 사용하는 것이 좋습니다.

str = str.replace(/X/g, '');

여기서 g는 전역을 의미하므로 전체 문자열을 통과하고 모든 X를 ''로 바꿉니다. X와 x를 모두 바꾸려면 간단히 다음과 같이 말합니다.

str = str.replace(/X|x/g, '');

(내 바이올린 참조 : 바이올린 )


나는 이것이 효과가 있을지 모르지만 정답은 더 빠르고 짧게 실행된다. 다른 방법들보다 느리다고 알려진 것보다 RegEx를 최대한 피하는 것이 좋다
— evilReiko

2

안녕하세요 아래 코드를 사용해보십시오

public class RemoveCharacter {

    public static void main(String[] args){
        String str = "MXy nameX iXs farXazX";
        char x = 'X';
        System.out.println(removeChr(str,x));
    }

    public static String removeChr(String str, char x){
        StringBuilder strBuilder = new StringBuilder();
        char[] rmString = str.toCharArray();
        for(int i=0; i<rmString.length; i++){
            if(rmString[i] == x){

            } else {
                strBuilder.append(rmString[i]);
            }
        }
        return strBuilder.toString();
    }
}

x 대신 다른 문자열이 있다면 어떻게해야합니까? 좋은 해결책!
— Mona Jalal

2

바꾸기 대신 replaceAll을 사용하십시오.

str = str.replaceAll("X,"");

원하는 답변을 제공합니다.


replace는 replaceAll을 사용하여 종료됩니다. 구현을 살펴보십시오. 이 문자열 #이 구현 교체하는 방법입니다 :return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString()));
— Sal_Vader_808

0
package com.acn.demo.action;

public class RemoveCharFromString {

    static String input = "";
    public static void main(String[] args) {
        input = "abadbbeb34erterb";
        char token = 'b';
        removeChar(token);
    }

    private static void removeChar(char token) {
        // TODO Auto-generated method stub
        System.out.println(input);
        for (int i=0;i<input.length();i++) {
            if (input.charAt(i) == token) {
            input = input.replace(input.charAt(i), ' ');
                System.out.println("MATCH FOUND");
            }
            input = input.replaceAll(" ", "");
            System.out.println(input);
        }
    }
}

input = "deletes all blanks too";제공 "deletesalllankstoo"
— 카플란

0

다음은 문자열로 전달 된 모든 문자를 제거하는 람다 함수입니다

BiFunction<String,String,String> deleteChars = (fromString, chars) -> {
  StringBuilder buf = new StringBuilder( fromString );
  IntStream.range( 0, buf.length() ).forEach( i -> {
    while( i < buf.length() && chars.indexOf( buf.charAt( i ) ) >= 0 )
      buf.deleteCharAt( i );
  } );
  return( buf.toString() );
};

String str = "TextX XYto modifyZ";
deleteChars.apply( str, "XYZ" ); // –> "Text to modify"

이 솔루션은 replace()문자를 제거 할 때 결과 문자열 이 시작 문자열보다 커지지 않는다는 점을 고려합니다. 그것은 피할 수 있도록 할당과가 문자 현명한 추가하면서 복사 반복 StringBuilder으로 replace()한다.
무의미한 세대 Pattern와 Matcher인스턴스 의 언급은 말할 것도없이 replace()제거 할 필요는 없습니다. 이 솔루션
과 달리 replace()한 번에 여러 문자를 삭제할 수 있습니다.


Lambdas / 함수 프로그래밍은 현재 매우 열악하지만 선택한 답변보다 10 배 더 긴 솔루션을 만드는 데 사용하면 IMHO를 정당화 할 수 없으므로 다운 투표가 가능합니다.
— Volksman

str.replace("…", "")생성 private Pattern(…)된 패턴 호출을 인스턴스화 한 다음 호출합니다 public String replaceAll(String repl). 따라서 다음과 같은 함수 호출이 발생했습니다. return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); – Sal_Vader_808 주석을 참조하십시오. 내 엉덩이 람다 솔루션 보다 약 3 배 더 길다 . 그리고 여기 왜 엉덩이 람다 솔루션이 더 빠른지 잘 설명 되어 있습니다. 왜 Java의 String :: replace ()가 그렇게 느립니까?
— Kaplan

그 자체로 : 솔루션의 크기에 관한 것이라면 다른 솔루션의 두 배나 외부 라이브러리가 필요한 솔루션이 더 비판의 대상이 될 것입니다. Java 8 이후 몇 년 동안 언어의 일부였던 언어 확장은 실제로 엉덩이 가 아닙니다 . 스코어링 시스템의 일반적인 문제점은 시간 계수가 솔루션의 품질보다 더 무겁다는 것입니다. 결과적으로 더 최신의 솔루션이 더 나은 솔루션이 점점 더 뒷받침되고 있습니다.
— Kaplan

실행 속도가 아닌 코드 측면에서 10 배 더 오래 언급했습니다. 호출 될 때마다 정규식 패턴을 컴파일하는 것은 속도가 훨씬 느릴 수 있습니다. 이러한 정규 표현식을 고주파수로 사용하는 경우 컴파일 된 매처를 캐시하고 재사용해야합니다 (OP는 사용 된 시나리오를 말하지 않습니다-양식 제출에서 데이터를 정리하는 드문 시나리오 일 수도 있고 타이트하게 사용될 수도 있습니다 루프는 초당 1000 번 호출됩니다).
— Volksman

성능 문제와 관련하여 제공된 다양한 답변에 대한 빠른 벤치 마크를 실행하는 새로운 답변을 추가했습니다. OP 가이 작업을 자주 수행하는 경우 후드 아래에서 정규 표현식 패턴을 반복적으로 재 컴파일하는 것이 매우 비싸기 때문에 String.replace () 옵션을 피해야합니다.
— Volksman

0

현재 선택된 답변으로 인해 많은 비용이 드는 정규 표현식 작업에 대한 우려를 확인하는 성능 벤치 마크를 통한 주요 답변 평가

제공된 답변은 3 가지 주요 스타일로 제공됩니다 (JavaScript 답변을 무시하고;)).

  • String.replace (charsToDelete, "")를 사용하십시오. 후드 아래에서 정규 표현식을 사용합니다.
  • Lambda 사용
  • 간단한 Java 구현 사용

코드 크기 측면에서 String.replace가 가장 간결합니다. 간단한 Java 구현은 Lambda보다 약간 작고 깨끗합니다 (IMHO) (잘못하지 마십시오-Lambdas를 적절한 곳에서 자주 사용합니다)

실행 속도는 가장 빠르거나 느리게 진행되었습니다. 간단한 Java 구현, Lambda 및 String.replace () (정규식 호출).

가장 빠른 구현은 StringBuilder 버퍼를 가능한 최대 결과 길이에 미리 할당 한 다음 "chars to delete"문자열에없는 문자를 버퍼에 추가하기 위해 조정 된 간단한 Java 구현이었습니다. 이렇게하면 문자열> 16 자 길이 (StringBuilder의 기본 할당)에서 발생하는 재 할당을 피할 수 있으며 발생하는 문자열의 복사본에서 문자를 삭제하는 "슬라이드 왼쪽"성능 적중을 피할 수 있습니다. Lambda 구현입니다.

아래 코드는 간단한 벤치 마크 테스트를 실행하여 각 구현을 1,000,000 회 실행하고 경과 시간을 기록합니다.

정확한 결과는 각 실행마다 다르지만 성능 순서는 변경되지 않습니다.

Start simple Java implementation
Time: 157 ms
Start Lambda implementation
Time: 253 ms
Start String.replace implementation
Time: 634 ms

Lambda 구현 (Kaplan의 답변에서 복사 한대로)은 삭제중인 문자의 오른쪽에있는 모든 문자 중 "하나씩 왼쪽으로 이동"을 수행하므로 속도가 느려질 수 있습니다. 삭제가 필요한 문자가 많은 긴 문자열의 경우 분명히 나빠질 수 있습니다. 또한 Lambda 구현 자체에 약간의 오버 헤드가있을 수 있습니다.

String.replace 구현은 정규식을 사용하며 각 호출에서 정규식 "컴파일"을 수행합니다. 이것의 최적화는 정규 표현식을 직접 사용하고 매번 컴파일하는 비용을 피하기 위해 컴파일 된 패턴을 캐시하는 것입니다.

package com.sample;

import java.util.function.BiFunction;
import java.util.stream.IntStream;

public class Main {

    static public String deleteCharsSimple(String fromString, String charsToDelete)
    {
        StringBuilder buf = new StringBuilder(fromString.length()); // Preallocate to max possible result length
        for(int i = 0; i < fromString.length(); i++)
            if (charsToDelete.indexOf(fromString.charAt(i)) < 0)
                buf.append(fromString.charAt(i));   // char not in chars to delete so add it
        return buf.toString();
    }

    static public String deleteCharsLambda(String fromString1, String charsToDelete)
    {
        BiFunction<String, String, String> deleteChars = (fromString, chars) -> {
            StringBuilder buf = new StringBuilder(fromString);
            IntStream.range(0, buf.length()).forEach(i -> {
                while (i < buf.length() && chars.indexOf(buf.charAt(i)) >= 0)
                    buf.deleteCharAt(i);
            });
            return (buf.toString());
        };

        return deleteChars.apply(fromString1, charsToDelete);
    }

    static public String deleteCharsReplace(String fromString, String charsToDelete)
    {
        return fromString.replace(charsToDelete, "");
    }


    public static void main(String[] args)
    {
        String str = "XXXTextX XXto modifyX";
        String charsToDelete = "X";  // Should only be one char as per OP's requirement

        long start, end;

        System.out.println("Start simple");
        start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++)
            deleteCharsSimple(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));

        System.out.println("Start lambda");
        start = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++)
            deleteCharsLambda(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));

        System.out.println("Start replace");
        start = System.currentTimeMillis();

        for (int i = 0; i < 1000000; i++)
            deleteCharsReplace(str, charsToDelete);

        end = System.currentTimeMillis();
        System.out.println("Time: " + (end - start));
    }
}

람다 함수가 의도 한대로 호출되면 타이밍은 다음과 같습니다 (아무도 람다 함수를 멤버 함수로 래핑하지 않습니다) . 또한 deleteCharsReplace ()가 잘못 구현되었습니다. 필요한 'X', 'Y'및 'Z'가 아닌 하나의 문자열 "XYZ"를 대체 fromString.replace("X", "").replace("Y", "").replace("Z", "");합니다. 이제 우리는 정확한 타이밍을 얻는다 : 간단한 시작 시간 : 759 | 람다 시작 시간 : 1092 | DeleteCharsLambda () 시작 시간 : 1420 | 수정 된 교체 시작 시간 : 4636
— Kaplan

"아무도 람다 함수를 멤버 함수로 래핑하지 않습니다"– 벤치 마크 시나리오에서 호출하여 다른 구현이 호출되는 방식과 일치하는 것을 제외하고는 람다 함수를 멤버 함수로 래핑하지 않습니다.
— Volksman

방금 OP가 단일 문자 의 모든 발생을 제거하는 것에 대해 요청 했지만 귀하의 답변으로 문자 집합을 처리하도록 범위가 변경 되었음을 알았습니다 . 내가 사용한 "허용 된"답변 구현은 여러 문자를 수용하도록 의도되지 않았으며 결코 의도되지 않았습니다. 이 벤치 마크 시간을 반영하여 위의 벤치 마크를 업데이트했습니다. BTW 여러 문자를 여러 번 호출하여 대체 할 수 있도록 범위를 늘리려면 비용이 많이 듭니다. 베터 ( "", "[XYZ]")에 완전히 대체 한 통화 전환
— Volksman

솔루션에 표시된대로 함수는 호출 될 때 한 번만 초기화됩니다. 함수 호출에 추가로 함수 정의를 멤버 함수로 랩핑하면 벤치 마크를 왜곡하는 유일한 효과가 있습니다.
— Kaplan

각 통화의 분산이 너무 높기 때문에 단일 통화를 수행하여 빠른 지속 시간 방법을 올바르게 벤치마킹하는 것은 사실상 불가능합니다. 따라서 벤치마킹에는 일반적으로 동일한 방법에 대한 여러 번의 반복 호출이 포함되며, 대안의 총 시간과 비교하기 위해 (또는 필요한 경우 평균을 계산하기 위해) 총 시간이 평가됩니다.
— Volksman

0

교체시 문자를 대괄호 안에 제거해야합니다. 예제 코드는 다음과 같습니다.

String s = "$116.42".replaceAll("[$]", "");

-3

str = str.replace("X", "");앞에서 언급 한대로 사용할 수 있으며 괜찮을 것입니다. 귀하의 정보 ''는 빈 (또는 유효한) 문자가 아니지만 '\0'입니다.

str = str.replace('X', '\0');대신 사용할 수 있습니다 .


9
이것은 올바르지 않습니다. '\ 0'은 실제 널 문자를 생성합니다. str.replace ( 'X', '\ 0')는 str.replace ( "X", "\ u0000")와 동일합니다. 이는 OP가 원하는 것이 아닙니다
— Andrey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.