Tôi có chuỗi "re\x{0301}sume\x{0301}"
(in như thế này: re & # x0301; sume & # x0301;) và tôi muốn đảo ngược nó thành "e\x{0301}muse\x{0301}r"
(e & # x0301; muse & # x0301; r). Tôi không thể sử dụng số reverse
của Perl vì nó xử lý các ký tự kết hợp như "\x{0301}"
làm các ký tự riêng biệt, vì vậy, tôi sẽ nhận được "\x{0301}emus\x{0301}er"
(& # x0301; emus & # x0301; er). Làm thế nào tôi có thể đảo ngược chuỗi, nhưng vẫn tôn trọng các ký tự kết hợp?Làm cách nào để đảo ngược chuỗi có chứa các ký tự kết hợp trong Perl?
Trả lời
Câu trả lời tốt nhất là sử dụng Unicode::GCString, as Sinan points out
tôi sửa đổi dụ Chas của một chút:
- Đặt mã hóa trên STDOUT để tránh cảnh báo "ký tự in rộng";
- Sử dụng một sự khẳng định lookahead tích cực (và không có chế độ giữ separator) trong
split
(không hoạt động sau 5.10, rõ ràng, vì vậy tôi loại bỏ nó)
Đó là cơ bản điều tương tự với một số điều chỉnh.
use strict;
use warnings;
binmode STDOUT, ":utf8";
my $original = "re\x{0301}sume\x{0301}";
my $wrong = reverse $original;
my $right = join '', reverse split /(\X)/, $original;
print <<HERE;
original: [$original]
wrong: [$wrong]
right: [$right]
HERE
Bạn có thể sử dụng \X special escape (phù hợp với một ký tự kết hợp không và tất cả các nhân vật kết hợp sau đây) với split
để tạo ra một danh sách các graphemes (với chuỗi rỗng giữa chúng), đảo ngược danh sách các graphemes, sau đó join
chúng trở lại với nhau:
#!/usr/bin/perl
use strict;
use warnings;
my $original = "re\x{0301}sume\x{0301}";
my $wrong = reverse $original;
my $right = join '', reverse split /(\X)/, $original;
print "original: $original\n",
"wrong: $wrong\n",
"right: $right\n";
Đối với những nhầm lẫn (như tôi là lúc đầu) về lý do tại sao có những chuỗi rỗng giữa graphemes, đó là vì 'split' được đảo ngược: nó sử dụng các dữ liệu đó là muốn tách. Chuỗi rỗng là "giữa" hai đồ thị là gì. Nó chỉ bằng cách bao gồm dấu phân cách trong kết quả mà bạn nhận được các đồ thị được trộn lẫn với kết quả "thực" - một chuỗi các chuỗi rỗng. Phương thức thay thế (và hơi nhanh hơn) tránh được đó là sử dụng 'm // g' để nắm bắt đồ thị thay vì:' join '', đảo ngược $ original = ~/(\ X)/g' –
Để làm rõ nhận xét của Michael , khi bạn sử dụng dấu ngoặc đơn bộ nhớ trong một regex bạn cung cấp để phân chia, bạn kích hoạt "chế độ giữ chân phân cách". Bạn lấy lại thứ nằm giữa các phần bạn đang tách ra. Tuy nhiên, bạn không cần phải làm điều đó. Mẫu (? = \ X) thực hiện điều tương tự mà không cần thêm bit. Không phải là chuỗi rỗng thực sự quan trọng đối với các chuỗi nhỏ. –
Bạn có quyền chỉ ra "chế độ lưu giữ dấu phân tách", cảm ơn bạn, điều đó hữu ích. Tuy nhiên, (? = \ X) không tương đương. Đối với giấy tờ chứng minh, hãy xem xét hai ví dụ này: chia/(a) /, "abc" là không tương đương với chia/(= a) /, "abc" và chia/(b + c) /, "abbcd" không tương đương với split/(? = b + c) /, "abbcd" – Flimm
Một số câu trả lời khác chứa các thành phần không hoạt động tốt. Đây là một ví dụ làm việc được kiểm tra trên Perl 5.12 và 5.14. Việc không chỉ định binmode sẽ làm cho đầu ra tạo ra các thông báo lỗi. Sử dụng xác nhận lookahead tích cực (và không có chế độ lưu giữ dấu tách) trong phần chia sẽ làm cho đầu ra không chính xác trên Macbook của tôi.
#!/usr/bin/perl
use strict;
use warnings;
use feature 'unicode_strings';
binmode STDOUT, ":utf8";
my $original = "re\x{0301}sume\x{0301}";
my $wrong = reverse $original;
my $right = join '', reverse split /(\X)/, $original;
print "original: $original\n",
"wrong: $wrong\n",
"right: $right\n";
Bạn có thể sử dụng Unicode::GCString:
Unicode :: GCString đối xử với Unicode chuỗi như một chuỗi các cụm grapheme mở rộng được xác định bởi Unicode chuẩn Phụ lụC# 29 [UAX # 29].
#!/usr/bin/env perl
use utf8;
use strict;
use warnings;
use feature 'say';
use open qw(:std :utf8);
use Unicode::GCString;
my $x = "re\x{0301}sume\x{0301}";
my $y = Unicode::GCString->new($x);
my $wrong = reverse $x;
my $correct = join '', reverse @{ $y->as_arrayref };
say "$x -> $wrong";
say "$y -> $correct";
Output:
résumé -> ́emuśer résumé -> émusér
- 1. Làm cách nào để đảo ngược các từ trong chuỗi?
- 2. Làm cách nào để đếm các ký tự trong Perl?
- 3. Chứa(), cách đảo ngược bằng lambda
- 4. Kết hợp các chuỗi ký tự
- 5. Perl: Sắp xếp các ký tự trong một chuỗi
- 6. Làm cách nào để đảo ngược chuỗi std ::?
- 7. Đảo ngược chuỗi trong C++
- 8. Chuỗi đảo ngược trong Python
- 9. Đảo ngược các từ trong một chuỗi
- 10. Đảo ngược chuỗi trong Python
- 11. Chuỗi chỉ chứa một tập hợp các ký tự
- 12. Làm cách nào để buộc JTable KHÔNG đảo ngược văn bản trong trường hợp nó chứa ký tự tiếng Ả Rập?
- 13. Đảo ngược Tìm trong một chuỗi
- 14. Làm cách nào để chuyển đổi chuỗi chứa chuỗi thoát ký tự thành char?
- 15. Thứ tự Đảo ngược
- 16. Làm cách nào để đảo ngược chuỗi UTF-8 tại chỗ?
- 17. Làm cách nào để kiểm tra xem chuỗi có chứa ký tự trong C#?
- 18. Đảo ngược thứ tự các từ (không phải ký tự) một cách hiệu quả trong một dãy ký tự
- 19. Làm thế nào để đảo ngược đầu ra sed?
- 20. Tại sao HighCharts đảo ngược thứ tự chuỗi của tôi?
- 21. Đảo ngược một chuỗi trong MIPS Assembly
- 22. Làm cách nào để đảo ngược một mảng
- 23. Đảo ngược regexp trong vim
- 24. Làm cách nào để xử lý các ký tự đặc biệt trong một regex Perl?
- 25. Làm cách nào để đảo ngược ma trận trong F #?
- 26. Làm cách nào để kiểm tra xem chuỗi Perl có chứa chữ cái không?
- 27. Làm thế nào tôi có thể nói cho ORM Django để đảo ngược thứ tự các kết quả truy vấn?
- 28. Làm cách nào để tách các ký tự không hợp lệ khỏi chuỗi trong JS?
- 29. Làm cách nào để biết liệu UIPageViewController có bị đảo ngược về phía trước hoặc bị đảo ngược không?
- 30. Đảo ngược kết quả bằng regexp
Wow. Tôi thích perl, nhưng biểu hiện phân chia đó khá là huyền diệu. Suy nghĩ đầu tiên của tôi là "sức mạnh vũ phu": tạo ra một chức năng để làm những gì mà sự phân chia làm - trả về một danh sách các chuỗi, mỗi mục trong đó đại diện cho một ký tự logic. Tuy nhiên bạn nhận được danh sách đó (gọi nó là @x), phần nối ('', đảo ngược (@x)) rõ ràng là sau, may mắn thay. – Roboprog
Magical? Làm thế nào? Nó chỉ là một regex không có tác dụng phụ và nó chỉ làm chính xác những gì bạn nhìn thấy. Nếu bạn nghĩ đó là phép thuật, bạn chưa từng thấy nghệ thuật đen thực sự của Perl. Bạn có thể gọi nó là thông minh (mặc dù tôi sẽ không), nhưng nó không phải là huyền diệu. Nó có lẽ chỉ là một cái gì đó bạn chưa từng sử dụng. –
Tôi đã thử chạy ví dụ này bằng Perl v5.12.4 và nó không hoạt động. Sử dụng/(\ X)/thay vào đó. Không quan tâm, câu trả lời này có hoạt động trong các phiên bản trước của Perl không, hoặc chúng ta có bỏ lỡ điều hiển nhiên không? – Flimm