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


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()한다.
무의미한 세대 PatternMatcher인스턴스 의 언급은 말할 것도없이 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.