source

Java String의 Unicode 코드 포인트를 반복하려면 어떻게 해야 합니까?

itover 2022. 11. 2. 21:31
반응형

Java String의 Unicode 코드 포인트를 반복하려면 어떻게 해야 합니까?

에 대해서는 알고 있습니다만, 이 인덱스는char코드 포인트 오프셋이 아닌 오프셋.

저는 다음과 같은 것을 시도해 보려고 합니다.

  • 를 사용하여char지표로
  • 테스트:char고위험군 범위에 있다
    • 만약 그렇다면, 코드포인트를 얻기 위해 사용하고, 지수를 2씩 증가시킨다.
    • 그렇지 않은 경우 지정된 값을 사용합니다.char코드 포인트로 값을 매겨 지수를 1씩 증가시킵니다.

근데 제가 고민하는 게

  • 원래 높은 대용률 범위에 있는 코드포인트가 두 개로 저장될지는 잘 모르겠습니다.char값 또는 하나
  • 이것은 캐릭터를 통해 반복하는 매우 비싼 방법인 것 같다.
  • 누군가 더 나은 걸 생각해냈을 거야

네, Java는 문자열의 내부 표현에 UTF-16-esque 인코딩을 사용하고 있습니다.또, Java는 대용 스킴을 사용해 Basic Multilinguage Plane(BMP; 기본 다국어 플레인) 외부에 있는 문자를 인코딩합니다.

BMP 이외의 문자를 취급하는 경우는, Java String 의 문자를 반복하는 표준 방법을 다음에 나타냅니다.

final int length = s.length();
for (int offset = 0; offset < length; ) {
   final int codepoint = s.codePointAt(offset);

   // do something with the codepoint

   offset += Character.charCount(codepoint);
}

Java 8이 추가되어 다음 명령어가 반환됩니다.IntStream코드 포인트를 포함합니다.스트림을 직접 사용하여 스트림을 반복할 수 있습니다.

string.codePoints().forEach(c -> ...);

또는 스트림을 배열로 수집하여 for 루프를 사용합니다.

for(int c : string.codePoints().toArray()){
    ...
}

이러한 방법은 Jonathan Feinbergs의 솔루션보다 비용이 많이 들지만 읽기/쓰기가 더 빠르고 성능 차이는 거의 없습니다.

foreach 루프(ref)와 연동되는 회피 방법을 추가하려고 합니다.또, Java 8로 이행하면, 간단하게 Java 8의 새로운 String#codePoints 방식으로 변환할 수 있습니다.

다음과 같이 foreach와 함께 사용할 수 있습니다.

 for(int codePoint : codePoints(myString)) {
   ....
 }

방법은 다음과 같습니다.

public static Iterable<Integer> codePoints(final String string) {
  return new Iterable<Integer>() {
    public Iterator<Integer> iterator() {
      return new Iterator<Integer>() {
        int nextIndex = 0;
        public boolean hasNext() {
          return nextIndex < string.length();
        }
        public Integer next() {
          int result = string.codePointAt(nextIndex);
          nextIndex += Character.charCount(result);
          return result;
        }
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  };
}

또는 문자열을 int 코드 포인트 배열로 변환하는 경우(코드가 코드 포인트 int 배열을 보다 쉽게 사용할 수 있는 경우) (위의 접근 방식보다 더 많은 RAM을 사용할 수 있습니다)

 public static List<Integer> stringToCodePoints(String in) {
    if( in == null)
      throw new NullPointerException("got null");
    List<Integer> out = new ArrayList<Integer>();
    final int length = in.length();
    for (int offset = 0; offset < length; ) {
      final int codepoint = in.codePointAt(offset);
      out.add(codepoint);
      offset += Character.charCount(codepoint);
    }
    return out;
  }

감사하게도 UTF-16(자바의 내부 문자열 표현)의 대리 쌍성을 안전하게 처리하는 "codePointAt"를 사용합니다.

코드 포인트에 대한 반복은 Sun에서 기능 요청으로 제출됩니다.

'Sun Bug 엔트리'

또한 String CodePoints에서 반복하는 방법에 대한 예도 있습니다.

언급URL : https://stackoverflow.com/questions/1527856/how-can-i-iterate-through-the-unicode-codepoints-of-a-java-string

반응형