문자열에 ASCII 만 포함되어 있는지 확인하는 방법은 무엇입니까?


120

문자가 문자이면 호출이 Character.isLetter(c)반환 true됩니다. 그러나 StringASCII의 기본 문자 만 포함되어 있는지 빠르게 찾을 수있는 방법이 있습니까?

답변:


128

에서 구아바 이후 19.0, 당신은 사용할 수 있습니다 :

boolean isAscii = CharMatcher.ascii().matchesAllOf(someString);

이것은 현재 사용되지 않는 싱글 톤이 아닌 matchesAllOf(someString)팩토리 방법에 의존 하는 방법을 사용합니다 .ascii()ASCII

여기서 ASCII에는 탭, 줄 바꿈 / 반환과 같이 인쇄 할 수없는 문자 (공백)를 포함한 모든 ASCII 문자가 포함 되며 코드 및 코드도 포함 됩니다.0x20BEL0x07DEL0x7F

이 코드는 이전 버전의 주석에 코드 포인트가 표시되어 있어도 코드 포인트가 아닌 문자를 잘못 사용합니다. 다행히도 값이 U+010000이상인 코드 포인트를 만드는 데 필요한 문자는 ASCII 범위를 벗어난 값을 가진 두 개의 서로 게이트 문자를 사용합니다. 따라서이 메서드는 이모티콘이 포함 된 문자열에서도 ASCII 테스트에 성공합니다.

ascii()메서드가 없는 이전 Guava 버전의 경우 다음과 같이 작성할 수 있습니다.

boolean isAscii = CharMatcher.ASCII.matchesAllOf(someString);

31
+1 타사 라이브러리가 필요하지 않아도 좋지만 Colin의 답변은 훨씬 짧고 읽기 쉽습니다. 타사 라이브러리를 제안하는 것은 완벽하게 괜찮으며 반대 투표로 처벌해서는 안됩니다.
Jesper

1
또한 CharMatchers는 정말 믿을 수 없을 정도로 강력하며 이것보다 더 많은 일을 할 수 있음을 지적해야합니다. 또한 ASCII 외에 더 많은 사전 정의 된 CharMatcher가 있으며 사용자 지정 항목을 만들기위한 훌륭한 팩토리 메서드가 있습니다.
ColinD

7
CharMatcher.ASCII는 현재 사용되지 않으며 2018 년 6 월에 제거 될 예정입니다.
thisarattr

108

java.nio.charset.Charset으로 할 수 있습니다 .

import java.nio.charset.Charset;

public class StringUtils {

  public static boolean isPureAscii(String v) {
    return Charset.forName("US-ASCII").newEncoder().canEncode(v);
    // or "ISO-8859-1" for ISO Latin 1
    // or StandardCharsets.US_ASCII with JDK1.7+
  }

  public static void main (String args[])
    throws Exception {

     String test = "Réal";
     System.out.println(test + " isPureAscii() : " + StringUtils.isPureAscii(test));
     test = "Real";
     System.out.println(test + " isPureAscii() : " + StringUtils.isPureAscii(test));

     /*
      * output :
      *   Réal isPureAscii() : false
      *   Real isPureAscii() : true
      */
  }
}

문자열에서 비 ASCII 문자 감지


10
"이 클래스의 인스턴스는 여러 동시 스레드에서 사용하기에 안전하지 않습니다."라는 문서에 따르면 CharsetEncoder를 정적으로 만드는 것은 좋은 생각이 아닙니다.
pm_labs

@paul_sns, 당신이 맞습니다. CharsetEncoder는 스레드로부터 안전하지 않습니다 (그러나 Charset은 그렇습니다). 그래서 그것을 정적으로 만드는 것은 좋은 생각이 아닙니다.
RealHowTo

11
Java 1.7 이상 StandardCharsets.US_ASCII에서는 Charset.forName("US-ASCII").
Julian Lettner 2014 년

@RealHowTo 올바른 솔루션은 주석에 의존 할 필요가 없으며,이 문제를 해결하고 StandardCharsets? 다른 답변을 게시 할 수는 있지만이 고맙게도 대답을 수정하고 싶습니다.
Maarten Bodewes

77

여기에 라이브러리에 의존하지 않고 정규식을 사용하는 또 다른 방법이 있습니다.

다음 한 줄을 사용할 수 있습니다.

text.matches("\\A\\p{ASCII}*\\z")

전체 예제 프로그램 :

public class Main {
    public static void main(String[] args) {
        char nonAscii = 0x00FF;
        String asciiText = "Hello";
        String nonAsciiText = "Buy: " + nonAscii;
        System.out.println(asciiText.matches("\\A\\p{ASCII}*\\z"));
        System.out.println(nonAsciiText.matches("\\A\\p{ASCII}*\\z"));
    }
}

15
\\ A-입력 시작 ... \\ p {ASCII} *-모든 ASCII 문자 ... \\ z-입력 끝
Arne Deutsch

@ArneDeutsch 답변을 개선하고 참조 \P{Print}\P{Graph}설명을 포함해도 될까요? 당신은 왜 필요합니까 \A\z?
Maarten Bodewes 2017

그 정규식은 무엇입니까? $는 문자열의 끝이고 ^는 시작이며 \\ A \\ p \\ z에 대해 들어 본 적이 없습니다. javadoc에 대한 참조를 첨부 해 주시겠습니까?
deathangel908

@ deathangel908 \ A는 입력 시작입니다. \ z는 입력의 끝입니다. ^ 및 $는 MULTILINE 모드에서 다르게 작동하며 DOTALL은 \ A 및 \ z의 작동을 변경합니다. 참조 stackoverflow.com/a/3652402/1003157
레이몬드 Naseef

58

문자열을 반복하고 모든 문자의 값이 128 미만인지 확인합니다.

Java 문자열은 개념적으로 UTF-16으로 인코딩됩니다. UTF-16에서 ASCII 문자 집합은 0-127 값으로 인코딩되며 ASCII가 아닌 문자 (하나 이상의 Java 문자로 구성 될 수 있음)에 대한 인코딩은 숫자 0-127을 포함하지 않도록 보장됩니다.


27
Java 1.8을 사용하면 다음을 수행 할 수 있습니다.str.chars().allMatch(c -> c < 128)
Julian Lettner 2014 년

7
인쇄 가능한 문자를 원하는 c >= 0x20 && c < 0x7F경우 7 비트 인코딩의 처음 32 개 값이 제어 문자이고 최종 값 (0x7F)이이므로 테스트 할 수 있습니다 DEL.
Maarten Bodewes 2015

15

또는 IDN 클래스 에서 코드를 복사합니다 .

// to check if a string only contains US-ASCII code point
//
private static boolean isAllASCII(String input) {
    boolean isASCII = true;
    for (int i = 0; i < input.length(); i++) {
        int c = input.charAt(i);
        if (c > 0x7F) {
            isASCII = false;
            break;
        }
    }
    return isASCII;
}

1
1-문자가> = U + D800 때문도 2 숯불 유니 코드와 함께 작동
K3B가

그러나 ASCII에 인쇄 할 수없는 문자가 포함되어 있습니다 (정확하지만 예상되지 않을 수 있음). 그것은 직접 사용하는 것이 물론 가능하다 return false사용하는 대신 isASCII = false하고 break.
Maarten Bodewes

이것은 Oracle JDK의 코드입니다. 복사하면 법적 문제가 발생할 수 있습니다.
Arne Deutsch

11

Apache의 commons-lang3에는이 문제를 포함한 모든 종류의 '문제'에 대한 유용한 유틸리티 / 편의 방법이 포함되어 있습니다.

System.out.println(StringUtils.isAsciiPrintable("!@£$%^&!@£$%^"));

1
문자열에 탭 또는 줄 바꿈 문자가 포함 된 경우 isAsciiPrintable은 false를 반환합니다 (\ t \ r \ n).
TampaHaze

@TampaHaze는 내부적으로 모든 문자 값이 32에서 127 사이인지 확인하기 때문입니다. 그게 틀렸다고 생각합니다. 0에서 127까지 확인해야합니다
therealprashant 19

1
@therealprashant 메소드 이름이 isAscii이면 동의합니다. 그러나 isAsciiPrintable라는 이름의 메소드 존재는 그들이 의도적으로 0에서 31 문자를 제외했을 수 있음을 의미한다
TampaHaze

4

이 시도:

for (char c: string.toCharArray()){
  if (((int)c)>127){
    return false;
  } 
}
return true;

"Try this"는 항상 반대표를받습니다. 이것은 무엇을 합니까 ? 포함 된 항목과 포함되지 않은 항목은 무엇입니까? 그건 그렇고 메모리 크기도 두 배로 늘리기 때문에 반대표를 얻을 것입니다.
Maarten Bodewes 2017

1

문자열을 반복하고 charAt ()을 사용하여 문자를 가져옵니다. 그런 다음 그것을 int로 취급하고 원하는 유니 코드 값 (ASCII의 상위 집합)이 있는지 확인하십시오.

마음에 들지 않는 첫 번째 휴식.


1
private static boolean isASCII(String s) 
{
    for (int i = 0; i < s.length(); i++) 
        if (s.charAt(i) > 127) 
            return false;
    return true;
}

코드 전용 대답입니다. 이것이 무엇을하는지 표시하십시오. 즉,이 검사를 수행하면 인쇄 할 수없는 문자와 정의되지 않은 문자 (0x7F)가 포함되어 있음을 나타냅니다.
Maarten Bodewes 2017

장기 실행 프로그램이 관심있는 캐릭터를 찾지 못한 후이 사람이 나를 물었을 수 있습니다. charAt를 반환합니다 char. char먼저 int로 변환하지 않고 유형 이 int보다 큰지 직접 테스트 할 수 있습니까 ? 아니면 테스트가 자동으로 커버를 수행합니까? 아마도 당신은 할 수 있고 아마도 그렇게 할 수 있습니까? 나는 계속해서 이것을 int로 변환했습니다 if ((int)s.charAt(i) > 127). 내 결과가 다른지 확실하지 않지만 실행하는 것이 더 좋습니다. 우리는 다음을 볼 것입니다 :-\
harperville

0

가능했습니다. 꽤 문제입니다.

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;

public class EncodingTest {

    static CharsetEncoder asciiEncoder = Charset.forName("US-ASCII")
            .newEncoder();

    public static void main(String[] args) {

        String testStr = "¤EÀsÆW°ê»Ú®i¶T¤¤¤ß3¼Ó®i¶TÆU2~~KITEC 3/F Rotunda 2";
        String[] strArr = testStr.split("~~", 2);
        int count = 0;
        boolean encodeFlag = false;

        do {
            encodeFlag = asciiEncoderTest(strArr[count]);
            System.out.println(encodeFlag);
            count++;
        } while (count < strArr.length);
    }

    public static boolean asciiEncoderTest(String test) {
        boolean encodeFlag = false;
        try {
            encodeFlag = asciiEncoder.canEncode(new String(test
                    .getBytes("ISO8859_1"), "BIG5"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encodeFlag;
    }
}

0

String이 ASCII 문자 만 포함하면 true를 반환하고 그렇지 않으면 false를 반환합니다.

Charset.forName("US-ASCII").newEncoder().canEncode(str)

비 ASCII를 제거하려면 다음 코드를 참조하십시오.

if(!Charset.forName("US-ASCII").newEncoder().canEncode(str)) {
                        str = str.replaceAll("[^\\p{ASCII}]", "");
                    }

-2
//return is uppercase or lowercase
public boolean isASCIILetter(char c) {
  return (c > 64 && c < 91) || (c > 96 && c < 123);
}

코드는 4 가지 마법으로 만 답하고 그것이 무엇을하는지 설명 하지 않습니다 . 조정하십시오.
Maarten Bodewes
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.