Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/421.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript RegExp+;单词边界+;unicode字符_Javascript_Regex_Unicode - Fatal编程技术网

Javascript RegExp+;单词边界+;unicode字符

Javascript RegExp+;单词边界+;unicode字符,javascript,regex,unicode,Javascript,Regex,Unicode,我正在构建搜索,我将使用javascript自动完成它。我来自芬兰(芬兰语),所以我必须处理一些特殊的字符,如ä、ö和å 当用户在搜索输入字段中键入文本时,我会尝试将文本与数据匹配 下面是一个简单的示例,如果用户键入例如“ää”则无法正常工作。“äl”也是一样 那么,如何让这些ä、ö和å字符与javascript正则表达式一起使用呢 我想我应该使用unicode代码,但我应该怎么做呢?这些字符的代码为: [\u00C4\u00E4\u00C5\u00E5\u00D6\u00F6] =>我的想法

我正在构建搜索,我将使用javascript自动完成它。我来自芬兰(芬兰语),所以我必须处理一些特殊的字符,如ä、ö和å

当用户在搜索输入字段中键入文本时,我会尝试将文本与数据匹配

下面是一个简单的示例,如果用户键入例如“ää”则无法正常工作。“äl”也是一样

那么,如何让这些ä、ö和å字符与javascript正则表达式一起使用呢

我想我应该使用unicode代码,但我应该怎么做呢?这些字符的代码为: [\u00C4\u00E4\u00C5\u00E5\u00D6\u00F6]


=>我的想法是用代表芬兰语字母的代码进行搜索

newregexp(“\\b”+ascionly(searchterm),“gi”).test(ascionly(title))

我最初的想法是使用普通的
encodeURI
,但是%符号似乎干扰了regexp


我编写了一个粗糙的函数,使用encodeURI对代码超过128的每个字符进行编码,但删除其%并在开头添加“QQ”。这不是最好的标记,但我无法使用非字母数字。

在使用Unicode时,我注意到
\b
有一些非常奇怪的地方:

/\bo/.test("pop"); // false (obviously)
/\bä/.test("päp"); // true (what..?)

/\Bo/.test("pop"); // true
/\Bä/.test("päp"); // false (what..?)

似乎
\b
\b
的含义是相反的,但仅当与非ASCII Unicode一起使用时?这里可能有更深层次的东西,但我不确定是什么


在任何情况下,似乎单词边界是问题所在,而不是Unicode字符本身。也许您应该将
\b
替换为
(^ |[\s\\/-\u&])
,因为这似乎是正确的。(不过,要让你的符号列表比我的更全面。)

正则表达式和单词边界
\b
匹配字符串开头和超出正常256字节范围的起始字符似乎有问题

不要使用
\b
,尝试使用
(?:^ |\\s)

细分:

(?:
括号
()
在正则表达式中构成捕获组。括号以问号开头,冒号
?:
构成非捕获组。它们只是将术语分组在一起

^
插入符号与字符串的开头匹配

|
条形图是“或”运算符

\s
匹配空格(在字符串中显示为
\\s
,因为我们必须转义反斜杠)

关闭组


因此,我们不使用与单词边界匹配且不适用于unicode字符的
\b
,而是使用与字符串或空格开头匹配的非捕获组。

JavaScript正则表达式中的
\b
字符类仅在简单的ASCII编码中有用
\b
\w
\w
集合或
\w
与字符串开头或结尾之间边界的快捷代码。这些字符集只考虑ASCII“word”字符,其中
\w
等于
[a-zA-Z0-9\]
\w
是该类的否定

这使得RegEx字符类在很大程度上无法处理任何真正的语言


\s
应该适用于您想要执行的操作,前提是搜索词仅由空格分隔。

我建议您在使用Unicode中的特定字符集时使用,该库的作者绘制了所有类型的区域字符集,使使用不同语言的工作更容易。

我也遇到过类似的问题,但我不得不替换一组术语。如果文本中两个术语相邻(因为它们的边界重叠),我发现所有的解决方案都不起作用。所以我不得不使用一种稍加修改的方法:

var text = "Ještě. že; \"už\" à. Fürs, 'anlässlich' že že že.";
var terms = ["à","anlässlich","Fürs","už","Ještě", "že"];
var replaced = [];
var order = 0;
for (i = 0; i < terms.length; i++) {
    terms[i] = "(^\|[ \n\r\t.,;'\"\+!?-])(" + terms[i] + ")([ \n\r\t.,;'\"\+!?-]+\|$)";
}
var re = new RegExp(terms.join("|"), "");
while (true) {
    var replacedString = "";
    text = text.replace(re, function replacer(match){
        var beginning = match.match("^[ \n\r\t.,;'\"\+!?-]+");
        if (beginning == null) beginning = "";
        var ending = match.match("[ \n\r\t.,;'\"\+!?-]+$");
        if (ending == null) ending = "";
        replacedString = match.replace(beginning,"");
        replacedString = replacedString.replace(ending,"");
        replaced.push(replacedString);
        return beginning+"{{"+order+"}}"+ending;
    });
if (replacedString == "") break;
order += 1;
}
var text=“Ještěe.že;\'už\'Fürs,'anlässlich'žeže.”;
var术语=[“a”、“anlässlich”、“Fürs”、“už”、“Ještě”、“že”];
var替换=[];
var阶数=0;
对于(i=0;i
请参阅小提琴中的代码:

正则表达式的灵感来自:


我不能说,我觉得这个解决方案很优雅…

这个问题很老了,但我认为我找到了一个更好的解决方案,用于unicode字母正则表达式中的边界。 使用XRegExp库可以实现有效的\b边界来扩展此

XRegExp('(?=^|$|[^\\p{L}])')
结果是4000多个字符长,但它似乎非常有效


一些解释:(?=)是一个零长度的前瞻,用于查找开始或结束边界或非字母unicode字符。最重要的想法是前瞻性,因为\b没有捕获任何东西:它只是对或错。

您要寻找的是Unicode单词边界标准:

这里有一个JavaScript实现(uncodejs.wordbreak.js)


\b
是字母和非字母字符之间转换的快捷方式,反之亦然

更新和改进的答案:

随着ES2018中RegExs的
/u
修饰符的引入,您现在可以使用
\p{L}
表示任何unicode字母,并且
\p{L}
var text = "Ještě. že; \"už\" à. Fürs, 'anlässlich' že že že.";
var terms = ["à","anlässlich","Fürs","už","Ještě", "že"];
var replaced = [];
var order = 0;
for (i = 0; i < terms.length; i++) {
    terms[i] = "(^\|[ \n\r\t.,;'\"\+!?-])(" + terms[i] + ")([ \n\r\t.,;'\"\+!?-]+\|$)";
}
var re = new RegExp(terms.join("|"), "");
while (true) {
    var replacedString = "";
    text = text.replace(re, function replacer(match){
        var beginning = match.match("^[ \n\r\t.,;'\"\+!?-]+");
        if (beginning == null) beginning = "";
        var ending = match.match("[ \n\r\t.,;'\"\+!?-]+$");
        if (ending == null) ending = "";
        replacedString = match.replace(beginning,"");
        replacedString = replacedString.replace(ending,"");
        replaced.push(replacedString);
        return beginning+"{{"+order+"}}"+ending;
    });
if (replacedString == "") break;
order += 1;
}
XRegExp('(?=^|$|[^\\p{L}])')
const text = 'A Fé, o Império, e as terras viciosas';

text.split(/(?<=\p{L})(?=\P{L})|(?<=\P{L})(?=\p{L})/);

// ['A', ' Fé', ',', ' o', ' Império', ',', ' e', ' as', ' terras', ' viciosas']
new RegExp(`(?<![\u0400-\u04ff])${cyrillicSearchValue}(?![\u0400-\u04ff])`,'gi')