EDIT: Tôi chỉ nhận thấy bạn không thực sự rõ mà mô hình khớp ngôn ngữ mà bạn đang sử dụng. Vâng, tôi hy vọng một giải pháp Perl sẽ làm việc cho bạn, vì các cơ chế cần thiết có thể sẽ thực sự khó khăn trong bất kỳ ngôn ngữ nào khác. Ngoài ra, nếu bạn đang làm mẫu phù hợp với Unicode, Perl thực sự là lựa chọn tốt nhất có sẵn cho loại công việc cụ thể đó.
Khi biến $rx
dưới đây được thiết lập để mô hình thích hợp, đoạn này ít mã Perl:
my $data = "foo1 and Πππ 語語語 done";
while ($data =~ /($rx)/g) {
print "Got string: '$1'\n";
}
Tạo đầu ra này:
Got string: 'foo1 and '
Got string: 'Πππ '
Got string: '語語語 '
Got string: 'done'
Nghĩa là, nó kéo ra một chuỗi Latin, một chuỗi tiếng Hy Lạp, một chuỗi Hán, và một chuỗi tiếng Latin khác.Điều này là khá darned đóng cửa với những gì tôi nghĩ rằng bạn thực sự cần.
Lý do tôi không đăng bài này hôm qua là tôi đã nhận được các vùng lõi kỳ lạ. Bây giờ tôi biết tại sao.
Giải pháp của tôi sử dụng các biến từ vựng bên trong cấu trúc (??{...})
. Hóa ra rằng điều đó không ổn định trước v5.17.1, và chỉ được làm việc tốt nhất một cách tình cờ. Nó không thành công trên v5.17.0, nhưng thành công trên v5.18.0 RC0 và RC2. Vì vậy, tôi đã thêm một số use v5.17.1
để đảm bảo rằng bạn đang điều hành đủ gần đây để tin tưởng với phương pháp này.
Trước tiên, tôi quyết định rằng bạn không thực sự muốn chạy một loại tập lệnh giống nhau; bạn muốn chạy một loại tập lệnh giống nhau cộng với Thông thường và được kế thừa. Nếu không, bạn sẽ bị rối tung bởi dấu chấm câu và khoảng trắng và chữ số cho Common, và bằng cách kết hợp các ký tự cho Inherited. Tôi thực sự không nghĩ rằng bạn muốn những người đó làm gián đoạn hoạt động của bạn "tất cả cùng một kịch bản", nhưng nếu bạn làm thế, thật dễ dàng để ngừng xem xét những điều đó.
Vì vậy, điều chúng tôi làm là chú ý đến ký tự đầu tiên có loại tập lệnh khác với Thông thường hoặc Được kế thừa. Hơn thế nữa, chúng tôi trích xuất từ đó loại kịch bản thực sự là gì và sử dụng thông tin này để tạo mẫu mới là bất kỳ số ký tự nào có loại tập lệnh là Phổ biến, Kế thừa hoặc bất kỳ loại tập lệnh nào mà chúng tôi vừa tìm và lưu. Sau đó, chúng tôi đánh giá mô hình mới và tiếp tục.
Xin chào, tôi cho biết nó đã là lông, phải không?
Trong chương trình tôi sắp hiển thị, tôi đã để lại trong một số báo cáo gỡ lỗi đã nhận xét chỉ hiển thị những gì nó đang thực hiện. Nếu bạn bỏ ghi chú họ, bạn nhận được kết quả này cho thời gian qua, mà sẽ giúp hiểu được cách tiếp cận:
DEBUG: Got peekahead character f, U+0066
DEBUG: Scriptname is Latin
DEBUG: string to re-interpolate as regex is q{[\p{Script=Common}\p{Script=Inherited}\p{Script=Latin}]*}
Got string: 'foo1 and '
DEBUG: Got peekahead character Π, U+03a0
DEBUG: Scriptname is Greek
DEBUG: string to re-interpolate as regex is q{[\p{Script=Common}\p{Script=Inherited}\p{Script=Greek}]*}
Got string: 'Πππ '
DEBUG: Got peekahead character 語, U+8a9e
DEBUG: Scriptname is Han
DEBUG: string to re-interpolate as regex is q{[\p{Script=Common}\p{Script=Inherited}\p{Script=Han}]*}
Got string: '語語語 '
DEBUG: Got peekahead character d, U+0064
DEBUG: Scriptname is Latin
DEBUG: string to re-interpolate as regex is q{[\p{Script=Common}\p{Script=Inherited}\p{Script=Latin}]*}
Got string: 'done'
Và đây cuối cùng là thỏa thuận lông lớn:
use v5.17.1;
use strict;
use warnings;
use warnings FATAL => "utf8";
use open qw(:std :utf8);
use utf8;
use Unicode::UCD qw(charscript);
# regex to match a string that's all of the
# same Script=XXX type
#
my $rx = qr{
(?=
[\p{Script=Common}\p{Script=Inherited}] *
(?<CAPTURE>
[^\p{Script=Common}\p{Script=Inherited}]
)
)
(??{
my $capture = $+{CAPTURE};
#####printf "DEBUG: Got peekahead character %s, U+%04x\n", $capture, ord $capture;
my $scriptname = charscript(ord $capture);
#####print "DEBUG: Scriptname is $scriptname\n";
my $run = q([\p{Script=Common}\p{Script=Inherited}\p{Script=)
. $scriptname
. q(}]*);
#####print "DEBUG: string to re-interpolate as regex is q{$run}\n";
$run;
})
}x;
my $data = "foo1 and Πππ 語語語 done";
$| = 1;
while ($data =~ /($rx)/g) {
print "Got string: '$1'\n";
}
Yeah, có Oughta được Một cách tốt hơn. Tôi không nghĩ là có.
Vì vậy, bây giờ, hãy tận hưởng.
Đóng nhưng không chính xác giống nhau: http://stackoverflow.com/questions/14942652/how-to-emulate-word-boundary-when-using-unicode-character-properties/14942906#14942906 Câu trả lời của tôi là ranh giới cho một lớp nhân vật duy nhất (và điều này áp dụng cho bất kỳ lớp nhân vật nào). Câu hỏi của bạn là về ranh giới giữa bất kỳ ngôn ngữ nào. – nhahtdh
@nhahtdh: Cảm ơn. Tôi ngạc nhiên là tôi không tìm thấy câu hỏi của bạn trong tìm kiếm của tôi. – hippietrail
Tôi nghĩ rằng tất cả mọi người nên đọc phần 2 của điều này: http://www.unicode.org/reports/tr24/ – nhahtdh