簡體   English   中英

如何忽略javascript正則表達式匹配中的重音?

[英]How to ignore acute accent in a javascript regex match?

我需要為這樣的正則表達式匹配一個像 'César' 這樣的詞/^cesar/i

是否有像/i這樣的選項來配置正則表達式,使其忽略重音符號?。 或者唯一的解決方案是使用像這樣的正則表達式/^césar/i

標准的 ecmascript regex 還沒有為 unicode 做好准備(請參閱http://blog.stevenlevithan.com/archives/javascript-regex-and-unicode )。

所以你必須使用外部正則表達式庫。 我過去使用過這個(帶有 unicode 插件): http : //xregexp.com/

在你的情況,你可能逃脫字符é和界定范圍的englobing E,E,E等

編輯:我剛剛看到亞歷克斯的評論:你會在 e 的重音等價物的范圍內找到。

您可以先從字符串中刪除重音並單獨測試:

var someString = 'César';
var bare = removeDiacritics(someString);

if (/^cesar/i.test(bare)) {
    // fail
}

請參閱此答案以了解removeDiacritics()的定義。

按照 Ja͢ck 的回答,這是applyDiacritics的實現,因此您可以實際匹配字符串而無需刪除或替換任何內容。

請注意,這不適用於許多正則表達式……照原樣接受:

 var diacriticsApplyMap = {'default':[ {'base':'A', 'letters':/[\A\Ⓐ\A\À\Á\Â\Ầ\Ấ\Ẫ\Ẩ\Ã\Ā\Ă\Ằ\Ắ\Ẵ\Ẳ\Ȧ\Ǡ\Ä\Ǟ\Ả\Å\Ǻ\Ǎ\Ȁ\Ȃ\Ạ\Ậ\Ặ\Ḁ\Ą\Ⱥ\Ɐ]/g}, {'base':'AA','letters':/[\Ꜳ]/g}, {'base':'AE','letters':/[\Æ\Ǽ\Ǣ]/g}, {'base':'AO','letters':/[\Ꜵ]/g}, {'base':'AU','letters':/[\Ꜷ]/g}, {'base':'AV','letters':/[\Ꜹ\Ꜻ]/g}, {'base':'AY','letters':/[\Ꜽ]/g}, {'base':'B', 'letters':/[\B\Ⓑ\B\Ḃ\Ḅ\Ḇ\Ƀ\Ƃ\Ɓ]/g}, {'base':'C', 'letters':/[\C\Ⓒ\C\Ć\Ĉ\Ċ\Č\Ç\Ḉ\Ƈ\Ȼ\Ꜿ]/g}, {'base':'D', 'letters':/[\D\Ⓓ\D\Ḋ\Ď\Ḍ\Ḑ\Ḓ\Ḏ\Đ\Ƌ\Ɗ\Ɖ\Ꝺ]/g}, {'base':'DZ','letters':/[\DZ\DŽ]/g}, {'base':'Dz','letters':/[\Dz\Dž]/g}, {'base':'E', 'letters':/[\E\Ⓔ\E\È\É\Ê\Ề\Ế\Ễ\Ể\Ẽ\Ē\Ḕ\Ḗ\Ĕ\Ė\Ë\Ẻ\Ě\Ȅ\Ȇ\Ẹ\Ệ\Ȩ\Ḝ\Ę\Ḙ\Ḛ\Ɛ\Ǝ]/g}, {'base':'F', 'letters':/[\F\Ⓕ\F\Ḟ\Ƒ\Ꝼ]/g}, {'base':'G', 'letters':/[\G\Ⓖ\G\Ǵ\Ĝ\Ḡ\Ğ\Ġ\Ǧ\Ģ\Ǥ\Ɠ\Ꞡ\Ᵹ\Ꝿ]/g}, {'base':'H', 'letters':/[\H\Ⓗ\H\Ĥ\Ḣ\Ḧ\Ȟ\Ḥ\Ḩ\Ḫ\Ħ\Ⱨ\Ⱶ\Ɥ]/g}, {'base':'I', 'letters':/[\I\Ⓘ\I\Ì\Í\Î\Ĩ\Ī\Ĭ\İ\Ï\Ḯ\Ỉ\Ǐ\Ȉ\Ȋ\Ị\Į\Ḭ\Ɨ]/g}, {'base':'J', 'letters':/[\J\Ⓙ\J\Ĵ\Ɉ]/g}, {'base':'K', 'letters':/[\K\Ⓚ\K\Ḱ\Ǩ\Ḳ\Ķ\Ḵ\Ƙ\Ⱪ\Ꝁ\Ꝃ\Ꝅ\Ꞣ]/g}, {'base':'L', 'letters':/[\L\Ⓛ\L\Ŀ\Ĺ\Ľ\Ḷ\Ḹ\Ļ\Ḽ\Ḻ\Ł\Ƚ\Ɫ\Ⱡ\Ꝉ\Ꝇ\Ꞁ]/g}, {'base':'LJ','letters':/[\LJ]/g}, {'base':'Lj','letters':/[\Lj]/g}, {'base':'M', 'letters':/[\M\Ⓜ\M\Ḿ\Ṁ\Ṃ\Ɱ\Ɯ]/g}, {'base':'N', 'letters':/[\N\Ⓝ\N\Ǹ\Ń\Ñ\Ṅ\Ň\Ṇ\Ņ\Ṋ\Ṉ\Ƞ\Ɲ\Ꞑ\Ꞥ]/g}, {'base':'NJ','letters':/[\NJ]/g}, {'base':'Nj','letters':/[\Nj]/g}, {'base':'O', 'letters':/[\O\Ⓞ\O\Ò\Ó\Ô\Ồ\Ố\Ỗ\Ổ\Õ\Ṍ\Ȭ\Ṏ\Ō\Ṑ\Ṓ\Ŏ\Ȯ\Ȱ\Ö\Ȫ\Ỏ\Ő\Ǒ\Ȍ\Ȏ\Ơ\Ờ\Ớ\Ỡ\Ở\Ợ\Ọ\Ộ\Ǫ\Ǭ\Ø\Ǿ\Ɔ\Ɵ\Ꝋ\Ꝍ]/g}, {'base':'OI','letters':/[\Ƣ]/g}, {'base':'OO','letters':/[\Ꝏ]/g}, {'base':'OU','letters':/[\Ȣ]/g}, {'base':'P', 'letters':/[\P\Ⓟ\P\Ṕ\Ṗ\Ƥ\Ᵽ\Ꝑ\Ꝓ\Ꝕ]/g}, {'base':'Q', 'letters':/[\Q\Ⓠ\Q\Ꝗ\Ꝙ\Ɋ]/g}, {'base':'R', 'letters':/[\R\Ⓡ\R\Ŕ\Ṙ\Ř\Ȑ\Ȓ\Ṛ\Ṝ\Ŗ\Ṟ\Ɍ\Ɽ\Ꝛ\Ꞧ\Ꞃ]/g}, {'base':'S', 'letters':/[\S\Ⓢ\S\ẞ\Ś\Ṥ\Ŝ\Ṡ\Š\Ṧ\Ṣ\Ṩ\Ș\Ş\Ȿ\Ꞩ\Ꞅ]/g}, {'base':'T', 'letters':/[\T\Ⓣ\T\Ṫ\Ť\Ṭ\Ț\Ţ\Ṱ\Ṯ\Ŧ\Ƭ\Ʈ\Ⱦ\Ꞇ]/g}, {'base':'TZ','letters':/[\Ꜩ]/g}, {'base':'U', 'letters':/[\U\Ⓤ\U\Ù\Ú\Û\Ũ\Ṹ\Ū\Ṻ\Ŭ\Ü\Ǜ\Ǘ\Ǖ\Ǚ\Ủ\Ů\Ű\Ǔ\Ȕ\Ȗ\Ư\Ừ\Ứ\Ữ\Ử\Ự\Ụ\Ṳ\Ų\Ṷ\Ṵ\Ʉ]/g}, {'base':'V', 'letters':/[\V\Ⓥ\V\Ṽ\Ṿ\Ʋ\Ꝟ\Ʌ]/g}, {'base':'VY','letters':/[\Ꝡ]/g}, {'base':'W', 'letters':/[\W\Ⓦ\W\Ẁ\Ẃ\Ŵ\Ẇ\Ẅ\Ẉ\Ⱳ]/g}, {'base':'X', 'letters':/[\X\Ⓧ\X\Ẋ\Ẍ]/g}, {'base':'Y', 'letters':/[\Y\Ⓨ\Y\Ỳ\Ý\Ŷ\Ỹ\Ȳ\Ẏ\Ÿ\Ỷ\Ỵ\Ƴ\Ɏ\Ỿ]/g}, {'base':'Z', 'letters':/[\Z\Ⓩ\Z\Ź\Ẑ\Ż\Ž\Ẓ\Ẕ\Ƶ\Ȥ\Ɀ\Ⱬ\Ꝣ]/g}, {'base':'a', 'letters':/[\a\ⓐ\a\ẚ\à\á\â\ầ\ấ\ẫ\ẩ\ã\ā\ă\ằ\ắ\ẵ\ẳ\ȧ\ǡ\ä\ǟ\ả\å\ǻ\ǎ\ȁ\ȃ\ạ\ậ\ặ\ḁ\ą\ⱥ\ɐ]/g}, {'base':'aa','letters':/[\ꜳ]/g}, {'base':'ae','letters':/[\æ\ǽ\ǣ]/g}, {'base':'ao','letters':/[\ꜵ]/g}, {'base':'au','letters':/[\ꜷ]/g}, {'base':'av','letters':/[\ꜹ\ꜻ]/g}, {'base':'ay','letters':/[\ꜽ]/g}, {'base':'b', 'letters':/[\b\ⓑ\b\ḃ\ḅ\ḇ\ƀ\ƃ\ɓ]/g}, {'base':'c', 'letters':/[\c\ⓒ\c\ć\ĉ\ċ\č\ç\ḉ\ƈ\ȼ\ꜿ\ↄ]/g}, {'base':'d', 'letters':/[\d\ⓓ\d\ḋ\ď\ḍ\ḑ\ḓ\ḏ\đ\ƌ\ɖ\ɗ\ꝺ]/g}, {'base':'dz','letters':/[\dz\dž]/g}, {'base':'e', 'letters':/[\e\ⓔ\e\è\é\ê\ề\ế\ễ\ể\ẽ\ē\ḕ\ḗ\ĕ\ė\ë\ẻ\ě\ȅ\ȇ\ẹ\ệ\ȩ\ḝ\ę\ḙ\ḛ\ɇ\ɛ\ǝ]/g}, {'base':'f', 'letters':/[\f\ⓕ\f\ḟ\ƒ\ꝼ]/g}, {'base':'g', 'letters':/[\g\ⓖ\g\ǵ\ĝ\ḡ\ğ\ġ\ǧ\ģ\ǥ\ɠ\ꞡ\ᵹ\ꝿ]/g}, {'base':'h', 'letters':/[\h\ⓗ\h\ĥ\ḣ\ḧ\ȟ\ḥ\ḩ\ḫ\ẖ\ħ\ⱨ\ⱶ\ɥ]/g}, {'base':'hv','letters':/[\ƕ]/g}, {'base':'i', 'letters':/[\i\ⓘ\i\ì\í\î\ĩ\ī\ĭ\ï\ḯ\ỉ\ǐ\ȉ\ȋ\ị\į\ḭ\ɨ\ı]/g}, {'base':'j', 'letters':/[\j\ⓙ\j\ĵ\ǰ\ɉ]/g}, {'base':'k', 'letters':/[\k\ⓚ\k\ḱ\ǩ\ḳ\ķ\ḵ\ƙ\ⱪ\ꝁ\ꝃ\ꝅ\ꞣ]/g}, {'base':'l', 'letters':/[\l\ⓛ\l\ŀ\ĺ\ľ\ḷ\ḹ\ļ\ḽ\ḻ\ſ\ł\ƚ\ɫ\ⱡ\ꝉ\ꞁ\ꝇ]/g}, {'base':'lj','letters':/[\lj]/g}, {'base':'m', 'letters':/[\m\ⓜ\m\ḿ\ṁ\ṃ\ɱ\ɯ]/g}, {'base':'n', 'letters':/[\n\ⓝ\n\ǹ\ń\ñ\ṅ\ň\ṇ\ņ\ṋ\ṉ\ƞ\ɲ\ʼn\ꞑ\ꞥ]/g}, {'base':'nj','letters':/[\nj]/g}, {'base':'o', 'letters':/[\o\ⓞ\o\ò\ó\ô\ồ\ố\ỗ\ổ\õ\ṍ\ȭ\ṏ\ō\ṑ\ṓ\ŏ\ȯ\ȱ\ö\ȫ\ỏ\ő\ǒ\ȍ\ȏ\ơ\ờ\ớ\ỡ\ở\ợ\ọ\ộ\ǫ\ǭ\ø\ǿ\ɔ\ꝋ\ꝍ\ɵ]/g}, {'base':'oi','letters':/[\ƣ]/g}, {'base':'ou','letters':/[\ȣ]/g}, {'base':'oo','letters':/[\ꝏ]/g}, {'base':'p','letters':/[\p\ⓟ\p\ṕ\ṗ\ƥ\ᵽ\ꝑ\ꝓ\ꝕ]/g}, {'base':'q','letters':/[\q\ⓠ\q\ɋ\ꝗ\ꝙ]/g}, {'base':'r','letters':/[\r\ⓡ\r\ŕ\ṙ\ř\ȑ\ȓ\ṛ\ṝ\ŗ\ṟ\ɍ\ɽ\ꝛ\ꞧ\ꞃ]/g}, {'base':'s','letters':/[\s\ⓢ\s\ß\ś\ṥ\ŝ\ṡ\š\ṧ\ṣ\ṩ\ș\ş\ȿ\ꞩ\ꞅ\ẛ]/g}, {'base':'t','letters':/[\t\ⓣ\t\ṫ\ẗ\ť\ṭ\ț\ţ\ṱ\ṯ\ŧ\ƭ\ʈ\ⱦ\ꞇ]/g}, {'base':'tz','letters':/[\ꜩ]/g}, {'base':'u','letters':/[\u\ⓤ\u\ù\ú\û\ũ\ṹ\ū\ṻ\ŭ\ü\ǜ\ǘ\ǖ\ǚ\ủ\ů\ű\ǔ\ȕ\ȗ\ư\ừ\ứ\ữ\ử\ự\ụ\ṳ\ų\ṷ\ṵ\ʉ]/g}, {'base':'v','letters':/[\v\ⓥ\v\ṽ\ṿ\ʋ\ꝟ\ʌ]/g}, {'base':'vy','letters':/[\ꝡ]/g}, {'base':'w','letters':/[\w\ⓦ\w\ẁ\ẃ\ŵ\ẇ\ẅ\ẘ\ẉ\ⱳ]/g}, {'base':'x','letters':/[\x\ⓧ\x\ẋ\ẍ]/g}, {'base':'y','letters':/[\y\ⓨ\y\ỳ\ý\ŷ\ỹ\ȳ\ẏ\ÿ\ỷ\ẙ\ỵ\ƴ\ɏ\ỿ]/g}, {'base':'z','letters':/[\z\ⓩ\z\ź\ẑ\ż\ž\ẓ\ẕ\ƶ\ȥ\ɀ\ⱬ\ꝣ]/g} ]}; // prepare the map to basically replace every letter in a regexp string for a character class with all letters in this map. for instance, /ai/ would become *something like* /[aáäã][iíï]/ and so on // this is however still breaking up with '[]' when they go in the highlights, since parentheses are not allowed inside diacriticsApplyMap.regex = []; for (var i = 0; i < diacriticsApplyMap.default.length; i++) { var item = diacriticsApplyMap.default[i]; var base = '(?:' + item.base + '|' + item.letters.source + ')'; diacriticsApplyMap.regex.push({ 'base': '$1' + base, 'letters': new RegExp('([^\\\\[\\\\\\\\])'+ base +'|^'+ base, 'g') }); } function applyDiacritics (str, which) { which = which || 'default'; var changes = diacriticsApplyMap[which]; for (var i = 0; i < changes.length; i++) { str = str.replace(changes[i].letters, changes[i].base); } return str; } // tests console.log(applyDiacritics('Jáck')); console.log(applyDiacritics('Jáck', 'regex')); console.log('Ja͢ck'.match(new RegExp(applyDiacritics('Jáck', 'regex'), 'gi'))); // not in the map console.log('Jäck'.match(applyDiacritics('Jáck', 'regex')));

一般來說,在 Lodash 庫的幫助下可以輕松完成,當您測試兩種類型的相同正則表達式輸入時 - 一種是由 lodash _deburr函數去毛刺的,另一種是原始用戶的輸入。 基於用戶名輸入表單的過濾示例(幾乎沒有 lodash _filter 函數的幫助):

import _ from 'lodash'

const input = inputFromYourFormInput
const users = ['Jiřina Žlutá', 'Aleš Úzký'];
const regex = new RegExp(input, 'gi');

const filtered = _.filter(users, (u) => {
  const debured = _.deburr(u)
  if (u.name.match(regex) || debured.match(regex))
    return u
})

在這種情況下,無論您的輸入是 Jirina Zluta 還是 Jiřina Žlutá _filter 函數都將返回新的過濾數組 [Jirina Zlutá]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM