Chỉ là sự bổ sung cho cả hai câu trả lời đã xuất sắc, nếu mâu thuẫn.
Tài liệu cho thư viện PCRE luôn nêu rằng "Phạm vi hoạt động trong chuỗi đối chiếu các giá trị ký tự". Đó là hơi mơ hồ, nhưng rất chính xác.
Nó đề cập đến đối chiếu bằng các chỉ số chỉ số trong các bảng ký tự bên trong của PCRE, có thể được thiết lập để khớp với ngôn ngữ hiện tại bằng cách sử dụng pcre_maketables
. Hàm đó xây dựng các bảng theo thứ tự giá trị char (tolower(i)
/toupper(i)
)
Nói cách khác, nó không khớp với thứ tự sắp xếp văn hóa thực tế (thông tin đối chiếu miền địa phương). Ví dụ, trong khi Đức xử lý ö giống như o trong đối chiếu từ điển, ö có giá trị làm cho nó xuất hiện bên ngoài phạm vi az trong tất cả các mã hóa ký tự chung được sử dụng cho tiếng Đức (ISO-8859-x, mã hóa unicode, v.v.) trường hợp này, PCRE sẽ căn cứ xác định xem liệu ö có nằm trong phạm vi [a-z]
trên giá trị mã đó hay không, thay vì bất kỳ thứ tự sắp xếp theo miền địa phương được xác định thực tế nào.
PHP chủ yếu được sao chép PCRE's documentation nguyên văn trong their docs. Tuy nhiên, họ đã thực sự đi đến nỗi đau thay đổi tuyên bố trên cho "Phạm vi hoạt động trong chuỗi đối chiếu ASCII". Tuyên bố đó đã có trong tài liệu ít nhất kể từ năm 2004.
Mặc dù vậy, tôi không hoàn toàn chắc chắn đó là sự thật.
Vâng, không phải trong mọi trường hợp, ít nhất.
Các PHP một cuộc gọi làm để pcre_maketables
... Từ PHP source:
#if HAVE_SETLOCALE
if (strcmp(locale, "C"))
tables = pcre_maketables();
#endif
Nói cách khác, nếu môi trường mà PHP được biên dịch có setlocale
và sự (LC_CTYPE) locale không được địa phương POSIX/C, thứ tự ký tự POSIX/C của môi trường thời gian chạy được sử dụng. Nếu không, các bảng PCRE mặc định được sử dụng - được tạo ra (bằng cách pcre_maketables
) khi PCRE được biên dịch - dựa trên trình biên dịch locale:
Chức năng này xây dựng một tập hợp các bảng tính cho nhân vật giá trị ít hơn 256. Chúng có thể được chuyển tới pcre_compile() để ghi đè lên các bảng bên trong, bên trong của PCRE (được thực hiện bởi pcre_maketables() khi PCRE được biên dịch).Bạn có thể muốn làm điều này nếu bạn đang sử dụng một miền địa phương không chuẩn. Hàm này sinh ra một con trỏ tới các bảng.
Trong khi Đức sẽ không thể khác nhau cho [a-z]
trong bất kỳ mã hóa ký tự thông thường, nếu chúng ta đang đối phó với EBCDIC, ví dụ, [a-z]
sẽ bao gồm ± và ~. Cấp, EBCDIC là một mã hóa ký tự tôi có thể nghĩ rằng nó không đặt a-z và A-Z trong chuỗi liên tục.
Trừ khi PCRE thực hiện một số phép thuật khi sử dụng EBCDIC (và có thể), trong khi rất khó, bạn có thể bao gồm những âm sắc trong môi trường chạy hoặc môi trường chạy PHP tối ưu nhất (sử dụng riêng, rất đặc biệt, tùy chỉnh của bạn) định nghĩa địa phương), bạn có thể, trong trường hợp EBCDIC, bao gồm các ký tự không mong muốn khác. Và đối với các phạm vi khác, "đối chiếu trong chuỗi ASCII" dường như không hoàn toàn chính xác.
ETA: tôi có thể tiết kiệm một số nghiên cứu bằng cách tìm kiếm câu trả lời của riêng Philip Hazel để một mối quan tâm tương tự:
Một vấn đề khác là với các lớp nhân vật dao động. Bạn sẽ nghĩ rằng [a-k] và [x-z] được xác định rõ ràng cho các tập lệnh latin nhưng không phải như vậy.
Họ chắc chắn được xác định rõ, là tương đương với [\ x61- \ X6B] và [\ x78- \ x7a], có nghĩa là, liên quan đến trật tự mã, không văn hóa để phân loại.
Điều này có thực sự đúng trong năm 2009 không? –
@WalterTross Vẫn đúng như ngày hôm nay khi nó đã trở lại sau đó. Nó không bao giờ về những gì đã được/là phổ biến, đó là về những gì MIGHT xảy ra với một số cấu hình kỳ lạ, và đảm bảo mã của bạn đủ mạnh để xử lý nó. –
@AlanStorm, bạn có thể cung cấp cấu hình lạ như vậy không? Tôi khá chắc chắn là không có! –