2010-05-21 33 views
19

Trong JavaScript:utf-8 từ regex ranh giới trong javascript

"ab abc cab ab ab".replace(/\bab\b/g, "AB"); 

cho đúng tôi:

"AB abc cab AB AB" 

Khi tôi sử dụng ký tự utf-8 mặc dù:

"αβ αβγ γαβ αβ αβ".replace(/\bαβ\b/g, "AB"); 

các word boundary operator dường như không hoạt động:

"αβ αβγ γαβ αβ αβ" 

Có giải pháp cho điều này không?

+1

JavaScript không sử dụng 'UTF-8' cho Unicode. Theo tiêu chuẩn, việc triển khai có thể sử dụng 'UCS-2' hoặc' UTF-16' mà tôi tin. Điều này có nghĩa là bạn đang hoạt động trên văn bản đã được chuyển đổi sang một trong các định dạng này hoặc bạn có thể hoạt động trên văn bản, mỗi "octet" (byte) của mỗi codepoint Unicode đã được chuyển đổi thành một trong các định dạng này, tùy thuộc vào cách bạn mã nhận được văn bản. – hippietrail

Trả lời

22

Xác nhận ranh giới từ chỉ phù hợp nếu một ký tự từ không được đặt trước hoặc theo sau bởi một ký tự từ khác (vì vậy .\b. bằng \W\w\w\W). Và \w được định nghĩa là [A-Za-z0-9_]. Vì vậy, \w không khớp với các ký tự Hy Lạp. Và do đó bạn không thể sử dụng \b cho trường hợp này.

gì bạn có thể làm thay vào đó là sử dụng điều này:

"αβ αβγ γαβ αβ αβ".replace(/(^|\s)αβ(?=\s|$)/g, "$1AB") 
+0

cảm ơn. Việc sử dụng ký hiệu lookahead (? = ...) có vẻ thú vị. Điều này có thể được thực hiện mà không có nó? – cherouvim

+3

@cherouvim: Không, nó sẽ tiêu thụ không gian sau từ đó là lúc bắt đầu cho lần tra cứu tiếp theo.Vì vậy, chỉ cần nhìn vào '" αβ αβ "', kết quả đầu tiên sẽ tiêu thụ '" αβ | αβ "' ('|' cho biết con trỏ bên trong) và phần cuối cùng sẽ không được so khớp vì không còn khoảng trắng phía trước. Nhưng vì xác nhận nhìn phía trước không tiêu thụ các ký tự, vị trí của con trỏ sau trận đấu đầu tiên sẽ là '" αβ | αβ "' và không gian hàng đầu được giữ nguyên cho trận đấu tiếp theo. – Gumbo

+1

Điều này không hoàn toàn giống với ranh giới từ. Ví dụ, nó không khớp với 'αβ! '. –

1

Không phải tất cả các hiện thực của RegEx gắn liền với động cơ Javascript một unicode biết.

Ví dụ: Microsofts JScript sử dụng trong IE bị giới hạn ở ANSI.

2

Không phải tất cả regexp thực hiện javascript đã hỗ trợ cho quảng cáo Unicode vì vậy bạn cần phải thoát khỏi nó

"αβ αβγ γαβ αβ αβ".replace(/\u03b1\u03b2/g, "AB"); // "AB ABγ γAB AB AB" 

Đối với việc lập bản đồ các ký tự mà bạn có thể có một cái nhìn tại http://htmlhelp.com/reference/html40/entities/symbols.html

Tất nhiên, điều này không giúp với vấn đề biên giới từ (như được giải thích trong các câu trả lời khác) nhưng ít nhất cũng cho phép bạn khớp các ký tự đúng cách

+0

Vậy tại sao bạn không sử dụng cùng một lần thoát Unicode cho chuỗi? – Gumbo

+0

Bởi vì một được phân tích dưới dạng một chuỗi và một là RegExp theo nghĩa đen - Tôi không chắc liệu nó có quan trọng hay không .. –

+3

Nhưng nếu việc thực hiện cụm từ thông dụng không hỗ trợ Unicode, trình tự thoát Unicode như '\ u03b1' như thế nào nghĩa vụ phải được giải thích? – Gumbo

1

Khi bạn đang xử lý Unicode và các từ tự nhiên, bạn có thể muốn cẩn thận hơn ith ranh giới hơn chỉ sử dụng \b. Xem this answer để biết chi tiết và chỉ đường.

2

tôi cần cái gì đó để có thể lập trình và xử lý dấu chấm câu, dấu ngoặc vv

http://jsfiddle.net/AQvyd/

var wordToReplace = '買い手', 
    replacementWord = '[[BUYER]]', 
    text = 'Mange 買い手 information. The selected Store and Classification will be the default on the สั่งซื้อ.' 

function replaceWord(text, wordToReplace, replacementWord) { 
    var re = new RegExp('(^|\\s|\\(|\'|"|,|;)' + wordToReplace + '($|\\s|\\)|\\.|\'|"|!|,|;|\\?)', 'gi'); 
    return text.replace(re, replacementWord); 
} 

Tôi đã viết một trình soạn thảo tài nguyên javascript vì vậy đây là lý do tại sao tôi đã tìm thấy trang này và cũng trả lời nó ra khỏi sự cần thiết kể từ khi tôi không thể tìm thấy một từ biên parametarized regexp mà làm việc tốt cho Unicode.

+0

Thực ra, tôi nên thoát khỏi "wordToReplace" bằng "\" trong các ký tự dành riêng. Tôi sẽ phải cập nhật điều đó. –

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