使用 Javascript 正则表达式匹配重音字符

IT技术 javascript regex unicode internationalization
2021-01-31 16:40:19

这是我今天遇到的一个有趣的片段:

/\ba/.test("a") --> true
/\bà/.test("à") --> false

然而,

/à/.test("à") --> true

首先,wtf?

其次,如果我想在单词的开头匹配一个带重音的字符,我该怎么做?(我真的很想避免使用像 那样的顶级选择器/(?:^|\s|'|\(\) ....

6个回答

这对我有用:

/^[a-z\u00E0-\u00FC]+$/i

此处的帮助下

从什么时候开始是ÿ法语字母 :D (这里的母语是...)
2021-03-16 16:40:19
此正则表达式包括 00F7,这是除法符号
2021-03-16 16:40:19
使用正则表达式,您会错过法语字母“ÿ”和“œ”。试着把/^[A-Za-z\u00C0-\u017F]+$/它们都拿来。
2021-03-22 16:40:19
大写字符的等价物是什么?
2021-04-11 16:40:19

/\bà/.test("à")不匹配的原因是因为“à”不是单词字符。转义序列\b仅在单词字符和非单词字符的边界之间匹配。/\ba/.test("a")匹配,因为“a”是一个单词字符。因此,字符串的开头(不是单词字符)和作为单词字符的字母“a”之间存在边界。

JavaScript 正则表达式中的单词字符定义为[a-zA-Z0-9_].

要匹配字符串开头的重音字符,只需使用^正则表达式开头字符(例如/^à/)。该字符表示字符串的开头(与\b在字符串内的任何单词边界处匹配的字符不同)。它是最基本和标准的正则表达式,所以它绝对不是最重要的。

Javascript 不符合The Unicode Standard,因为引用的标准非常清楚地指出像 à 这样的东西绝对是为了\w在正则表达式中匹配
2021-03-25 16:40:19
好吧,这解释了很多事情,但我想我在最初的问题中实际上说错了。我需要在单词的开头匹配,而不是字符串。我认为选择器会“过度”的原因是因为它需要匹配字符串的开头、空格、括号、逗号、句号......
2021-04-05 16:40:19
+1 我只会用该re.test()方法添加这一点,需要注意re.lastIndex包含最后一场比赛的偏移量属性的行为(并且是下一场比赛尝试将开始的地方)。这在这种情况下不适用,因为该方法应用于正则表达式文字,但是如果正则表达式对象存储在变量中然后多次使用,这很重要。
2021-04-07 16:40:19

Stack Overflow 也存在正则表达式中非 ASCII 字符的问题,您可以在此处找到它它们不处理单词边界,但可能会给您提供有用的提示。

还有另一个page,但他想匹配字符串而不是单词。

我不知道,现在也没有找到解决您问题的锚点,但是当我看到在我的第一个链接中使用了哪些怪物正则表达式时,您想要避免的组并没有超出我的意见你的解决方案。

const regex = /^[\-/A-Za-z\u00C0-\u017F ]+$/;
const test1 = regex.test("à");
const test2 = regex.test("Martinez-Cortez");
const test3 = regex.test("Leonardo da vinci");
const test4 = regex.test("ï");

console.log('test1', test1);
console.log('test2', test2);
console.log('test3', test3);
console.log('test4', test4);

基于 Wak 和 Cœur 的回答:

/^[\-/A-Za-z\u00C0-\u017F ]+$/

也适用于空格和破折号。

示例:列奥纳多·达·芬奇、马丁内斯-科尔特斯

您的示例不包含任何作为 OP 请求的重音字符
2021-03-22 16:40:19

如果您想匹配字母,无论它们是否带有重音符号,unicode 属性转义都会有所帮助。

/\p{Letter}*/u.test("à"); // true
/\p{Letter}/u.test('œ'); // true
/\p{Letter}/u.test('a'); // true
/\p{Letter}/u.test('3'); // false
/\p{Letter}/u.test('a'); // true

匹配单词的开头很棘手,但(?<=(?:^|\s))似乎可以解决问题。(?<= )是一个积极的回顾,确保在主要表达之前存在某些东西。(?: )是一个非捕获组,因此您在以后使用的任何匹配项中都不会引用此部分。然后,^如果未设置多行标志则匹配字符串的开头,如果设置了多行标志,\s则匹配行的开头,并且将匹配空白字符(空格/制表符/换行符)。

所以一起使用它们,它看起来像:

/(?<=(?:^|\s))\p{Letter}*/u

如果你想重音字符匹配字符串的开始,你会想要一个-ZA-Z一个否定的字符集。

/(?<=(?:^|\s))[^a-zA-Z]\p{Letter}*/u.match("bœ") // false
/(?<=(?:^|\s))[^a-zA-Z]\p{Letter}*/u.match("œb") // true

// Match characters, accented or not
let regex = /\p{Letter}+$/u;

console.log(regex.test("œb")); // true
console.log(regex.test("bœb")); // true
console.log(regex.test("àbby")); // true
console.log(regex.test("à3")); // false
console.log(regex.test("16 tons")); // true
console.log(regex.test("3 œ")); // true

console.log('-----');

// Match characters to start of line, only match characters

regex = /(?<=(?:^|\s))\p{Letter}+$/u;

console.log(regex.test("œb")); // true
console.log(regex.test("bœb")); // true
console.log(regex.test("àbby")); // true
console.log(regex.test("à3")); // false

console.log('----');

// Match accented character to start of word, only match characters

regex = /(?<=(?:^|\s))[^a-zA-Z]\p{Letter}+$/u;

console.log(regex.test("œb")); // true
console.log(regex.test("bœb")); // false
console.log(regex.test("àbby")); // true
console.log(regex.test("à3")); // false

这是迄今为止最好的答案- 当前的答案遗漏了许多字母并包括非字母字符。我添加了一个指向 MDN 页面的链接。
2021-03-17 16:40:19