2009-12-20 49 views
5

Tôi đang xây dựng một ngôn ngữ, một ngôn ngữ đồ chơi. Cú pháp \#0061 là nghĩa vụ phải chuyển đổi Unicode dành cho một nhân vật:Unicode để chuyển đổi chuỗi trong Java

String temp = yytext().subtring(2); 

Sau đó, sau đó cố gắng thêm '\u' vào chuỗi, tôi nhận thấy rằng tạo ra một lỗi.

Tôi cũng đã cố gắng "\\" + "u" + temp; cách này không thực hiện bất kỳ chuyển đổi nào.

Tôi về cơ bản đang cố chuyển đổi Unicode thành ký tự bằng cách chỉ cung cấp '0061' cho một phương thức, trợ giúp.

+0

Lưu ý rằng 16 bit (4 chữ số thập phân) không đủ để biểu diễn tất cả các ký tự trong Unicode. Trong java "\ u1234" ánh xạ tới một đơn vị điểm mã trong UTF-16, không giống như một ký tự. –

+0

Phụ lục: Trên thực tế, đó là loại dữ liệu java char ánh xạ tới các đơn vị điểm mã UTF-16, chứ không phải các ký tự Unicode thực tế. –

Trả lời

11

Vạch '#' và sử dụng Integer.parseInt("0061", 16) để chuyển đổi các chữ số thập phân sang số int. Sau đó truyền đến một số char.

(Nếu bạn đã thực hiện lexer bằng tay, một cách khác sẽ là thực hiện chuyển đổi khi đang bay khi lexer của bạn khớp với chữ unicode. Nhưng khi đọc lại câu hỏi, tôi thấy bạn đang sử dụng trình tạo từ khóa. di chuyển tốt!)

+1

Chỉ cần tò mò: làm thế nào bạn phát hiện ra rằng anh ta đang sử dụng một lexer? – BalusC

+1

@BalusC Vì 'yytext', biến số lex cụ thể –

+0

Đúng vậy Pascal –

0

\uXXXX là trình tự thoát. Trước khi thực thi nó đã được chuyển đổi thành giá trị ký tự thực tế, nó không được "đánh giá" trong lúc chạy.

Điều bạn có thể muốn làm là xác định ánh xạ từ cú pháp #XXXX tới các điểm mã Unicode và truyền chúng đến char.

2

Bạn cần chuyển đổi điểm mã cụ thể thành char. Bạn có thể làm điều đó với một chút giúp đỡ của regex:

String string = "blah #0061 blah"; 

Matcher matcher = Pattern.compile("\\#((?i)[0-9a-f]{4})").matcher(string); 
while (matcher.find()) { 
    int codepoint = Integer.valueOf(matcher.group(1), 16); 
    string = string.replaceAll(matcher.group(0), String.valueOf((char) codepoint)); 
} 

System.out.println(string); // blah a blah 

Sửa theo ý kiến, nếu nó là một dấu hiệu duy nhất, sau đó chỉ cần làm:

String string = "0061"; 
char c = (char) Integer.parseInt(string, 16); 
System.out.println(c); // a 
+0

Erm ... bạn không muốn triển khai một trình phân tích từ vựng bằng cách sử dụng đối sánh mẫu regex Java. –

+0

Điểm hợp lệ, tôi đã cập nhật câu trả lời cho phù hợp. – BalusC

+0

Tôi cần một cái gì đó giống như ví dụ đầu tiên bạn đăng. Tôi chạy mã làm thay đổi mô hình như tôi cần chúng tuy nhiên ReplaceAll không thay thế bất cứ điều gì. Chuỗi giống với chuỗi gốc: ( –

2

tôi đang về cơ bản cố gắng để chuyển đổi unicode thành ký tự bằng cách cung cấp chỉ '0061' cho một phương thức, trợ giúp.

char fromUnicode(String codePoint) { 
    return (char) Integer.parseInt(codePoint, 16); 
} 

Bạn cần phải xử lý đầu vào xấu và như vậy, nhưng điều đó sẽ làm việc khác.

Các vấn đề liên quan