2011-08-26 33 views
13

Làm cách nào để khớp một chữ cái từ bất kỳ ngôn ngữ nào bằng cách sử dụng regex trong python 3?Thư đối sánh bằng bất kỳ ngôn ngữ nào

re.match([a-zA-Z]) sẽ khớp với các ký tự ngôn ngữ tiếng Anh nhưng tôi muốn tất cả các ngôn ngữ được hỗ trợ cùng một lúc.

Tôi không muốn khớp với ' trong can't hoặc gạch dưới hoặc bất kỳ loại định dạng nào khác. Tôi muốn regex của tôi phù hợp: c, a, n, t, Å, é.

+0

Tôi không thể nghĩ ra một cách hợp lý để đi về việc này. Hầu hết các ngôn ngữ không khớp với bảng chữ cái tiếng Anh. Ví dụ, nếu bạn cố gắng để phù hợp với một 'k' trong tiếng Nhật, bạn sẽ không thể làm điều đó. Ngôn ngữ của họ chỉ chứa 'ka' 'ki' 'ku' 'ke' 'ko' nhưng chúng được biểu diễn bằng ký hiệu sao cho chữ K không khớp với bất kỳ ký tự cụ thể nào. Để làm việc này, về cơ bản bạn cần phải có một ngôn ngữ và "dịch" nó thành một tương đương tiếng Anh. Vì vậy, nếu bạn gặp "buổi sáng tốt" trong tiếng Nhật こ ん に ち は bạn sẽ phải "dịch" thành "konnichiwa" trước khi thực hiện một trận đấu regex. – Tony318

+3

@ Tony318 tôi tình cờ đã học chuyên ngành tiếng Nhật ... Cách tiếp cận đó là sai trên rất nhiều cấp độ ... – ty812

+3

thể trùng lặp của http://stackoverflow.com/questions/2039140/python-re-how-do-i- match-an-alpha-ký tự – Marty

Trả lời

16

Đối với Unicode việc regex bằng Python, tôi rất khuyên như sau:

  1. Sử dụng Matthew Barnett’s regex library thay vì tiêu chuẩn re, mà không thực sự thích hợp cho Unicode thường xuyên biểu thức.
  2. Chỉ sử dụng Python 3, không bao giờ Python 2. Bạn muốn tất cả các chuỗi của mình là chuỗi Unicode.
  3. Chỉ sử dụng các chuỗi ký tự với các điểm mã Unicode hợp lý/trừu tượng, không phải chuỗi byte được mã hóa.
  4. Đặt mã hóa trên luồng của bạn và quên nó đi. Nếu bạn thấy mình từng gọi theo cách thủ công .encode và như vậy, bạn gần như chắc chắn đang làm điều gì đó sai.
  5. Chỉ sử dụng một bản dựng rộng nơi các điểm mã và các đơn vị mã giống nhau, chưa từng bao giờ là một điểm hẹp - mà bạn có thể làm tốt để cân nhắc việc không được sử dụng cho tính mạnh mẽ của Unicode.
  6. Bình thường hóa tất cả các chuỗi đến thành NFD trên đường đi rồi NFC trên đường ra. Nếu không, bạn không thể có hành vi đáng tin cậy.

Khi bạn làm điều này, bạn có thể yên tâm viết mẫu mà bao gồm \w hoặc \p{script=Latin} hoặc \p{alpha}\p{lower} vv và biết rằng tất cả những sẽ làm những gì the Unicode Standard says they should. Tôi giải thích tất cả các doanh nghiệp này của Python Unicode kinh doanh regex chi tiết hơn in this answer. Câu chuyện ngắn là luôn sử dụng regex không phải re.

Để có tư vấn Unicode chung, tôi cũng có several talks from last OSCON về các biểu thức chính quy Unicode, hầu hết trong số đó không chỉ nói về Python, mà phần lớn là khả năng thích ứng.

Cuối cùng, luôn có this answer để đặt sự sợ hãi của Thiên Chúa (hoặc ít nhất, của Unicode) trong trái tim của bạn.

1

Tạo lớp đối sánh của tất cả các ký tự bạn muốn đối sánh. Điều này có thể trở thành rất, rất lớn. Không, không có thuật toán RegEx nào cho "Tất cả chữ Kanji";)

Có thể dễ dàng khớp với những gì bạn không muốn, nhưng thậm chí sau đó, lớp này sẽ trở nên cực kỳ lớn.

+0

Tôi đã không nhận ra nó sẽ rất khó khăn ... Tôi sẽ bắt đầu bằng cách tạo một biểu đồ của các ký tự trong tất cả các văn bản Tôi muốn xử lý ... – Baz

+0

Điều đó phụ thuộc vào động cơ regex. Bạn có thể kết hợp trên thuộc tính kịch bản trong một số công cụ, chẳng hạn như Perl, nơi bạn có thể chọn kịch bản Hán (những ký tự * Hán *, mặc dù chúng được người Nhật sử dụng và gọi là Kanji ở đó). – Joey

+0

Chắc chắn, bạn có thể làm điều đó cho * một * kịch bản một lần - nhưng không phải cho * mỗi * một cùng một lúc (Đừng discusss các problematics Han/Kanji đây ... đó là một chặng đường dài, lịch sử đẫm máu, không, nhiều ký tự không phải là hoàn toàn giống nhau) – ty812

4

Bạn có thể kết hợp trên

\p{L} 

đó phù hợp với bất kỳ điểm mã Unicode mà đại diện cho một lá thư của một kịch bản. Đó là, giả sử bạn thực sự có một công cụ regex Unicode có khả năng, mà tôi thực sự hy vọng Python sẽ có.

+0

cũng hoạt động trên Ruby :) – Aleksey

7

Có gì sai khi sử dụng trình tự đặc biệt \ w?

# -*- coding: utf-8 -*- 
import re 
test = u"can't, Å, é, and 中ABC" 
print re.findall('\w+', test, re.UNICODE) 
+1

'\ w' khớp với chữ số' [0-9] 'và dấu gạch dưới' _' – Toto

+1

Rất tốt, đó là câu trả lời đúng theo thư viện Python chuẩn (mặc dù tôi luôn sử dụng các ký tự Unicode). Lưu ý rằng theo [UTS # 18] (http://unicode.org/reports/tr18/#Categories), một từ "word" char à la '\ w' bao gồm 102,724 điểm mã trong Unicode 6.0 và là bất kỳ GC = L nào (100,520), GC = M (1,492), GC = Nd (420), GC = Nl (224), hoặc GC = Pc (10) điểm mã. Python 're' là một chút ngày, vì vậy đã không theo kịp với tiêu chuẩn, nhưng nó là gần-ish. Bạn có thể sử dụng 'regex' của Matthew Barnett thay vào đó nếu bạn muốn khớp chính xác với Unicode Standard; nó cũng cung cấp '\ p {alpha}', đó là những gì bạn muốn ở đây. – tchrist

+0

@ M42: Nó phức tạp hơn thế, nhưng có. Thư viện 're' bình thường của Python là [không tốt cho Unicode] (http://stackoverflow.com/questions/7063420/perl-compatible-regular-expression-pcre-in-python/7066413#7066413), mặc dù nó gần với [ RL1.2a] (http://unicode.org/reports/tr18/#Compatibility_Properties) nhưng thiếu các thuộc tính cơ bản cho mỗi [RL1.2] (http://unicode.org/reports/tr18/#Categories) và toàn bộ thuộc tính cho mỗi [RL2.7] (http://www.unicode.org/reports/tr18/tr18-14.html#Full_Properties). Đối với hầu hết mọi công cụ Unicode regex, bạn nên sử dụng thư viện 'regex' của Matthew Barnett. – tchrist

1
 
import re 

text = "can't, Å, é, and 中ABC" 
print(re.findall('\w+', text)) 

Điều này hoạt động bằng Python 3. Nhưng nó cũng khớp với dấu gạch dưới. Tuy nhiên điều này dường như để làm công việc như tôi muốn:

 
import regex 

text = "can't, Å, é, and 中ABC _ sh_t" 
print(regex.findall('\p{alpha}+', text)) 
0

Đối với ngôn ngữ Bồ Đào Nha, sử dụng thử cái này:

[a-zA-ZÀ-ú ]+ 
Các vấn đề liên quan