Javascript 正则表达式删除非字母字符,但保留重音字母

Javascript 正则表达式删除非字母字符,但保留重音字母,javascript,regex,string,diacritics,Javascript,Regex,String,Diacritics,我有西班牙语和其他语言的字符串,其中可能包含需要删除的通用特殊字符,如()、*,等等。但问题是,它也可能包含特殊的语言字符,如ñ、á、ó、í等,它们需要保留。因此,我尝试通过以下方式使用regexp: var desired = stringToReplace.replace(/[^\w\s]/gi, ''); 不幸的是,它正在删除所有特殊字符,包括与语言相关的字符。我不知道如何避免。也许有人可以建议 var desired = stringToReplace.replace(/[\u0000

我有西班牙语和其他语言的字符串,其中可能包含需要删除的通用特殊字符,如()、*,等等。但问题是,它也可能包含特殊的语言字符,如ñ、á、ó、í等,它们需要保留。因此,我尝试通过以下方式使用regexp:

var desired = stringToReplace.replace(/[^\w\s]/gi, '');
不幸的是,它正在删除所有特殊字符,包括与语言相关的字符。我不知道如何避免。也许有人可以建议

var desired = stringToReplace.replace(/[\u0000-\u007F][\W]/gi, '');
也许能奏效


另请参见此问题。

您可以尝试将非法字符列入黑名单,而不是将您接受的字符列入白名单:

var desired = stringToReplace.replace(/[-'`~!@#$%^&*()_|+=?;:'",.<>\{\}\[\]\\\/]/gi, '')
var desired=stringToReplace.replace(/[-'`~!@$%^&*(),.\{\\\[\]\\/]/gi',)

我建议使用Steven Levithan的优秀库及其应用程序

下面是一个从字符串中删除非拉丁单词字符的示例:

另请参见Steven Levithan本人的回答:


不幸的是,Javascript不支持(这正是适合您的正则表达式功能)。如果您可以选择更改语言,PHP(例如)可以执行以下操作:

preg_replace("/[^\pL0-9_\s]/", "", $str);
其中
\pL
匹配表示字母的任何Unicode字符(小写、大写、修改或未修改)

如果您必须坚持使用JavaScript,并且无法使用Tim Down建议的库,那么唯一的选择可能是黑名单或白名单。但是您的赏金提到黑名单实际上不是您的选择。因此您可能只需要手动包含相关语言中的特殊字符。因此你可以这样做:

var desired = stringToReplace.replace(/[^\w\sñáóí]/gi, '');
或者使用相应的Unicode序列:

var desired = stringToReplace.replace(/[^\w\s\u00F1\u00C1\u00F3\u00ED]/gi, '');

然后只需添加所有需要处理的字符。请注意,不区分大小写的修饰符也适用于Unicode序列。

注意!仅适用于16位代码点。此答案不完整

简短回答 所有阿拉伯数字拉丁字母的字符类为:
[0-0-9 0-9 A-0-9 A-0-9 A-0-9 A-0-9 A-0-9 A-0-9 A-0 0-0 0-0 0-9 7 7 7 7 7 7 7-0 0-7 7 7 7 7 7-0 0-0 0-0-0 0-0-0-0-0-0-0-0 0-0-0 0 0-0 0-0 0 0 0-7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-0-7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7]

要获得正则表达式,您可以使用,在
/^
前面加上前缀并附加
+$/
。这将匹配仅由拉丁字母和数字组成的字符串,如
“mérito”
“Schönheit”

要匹配非数字或非字母字符以将其删除,请在开头括号
[
后写一个
^
作为第一个字符,并在
/
前面加上
+//code>

我是怎么发现的?继续阅读

长答案:使用元编程! 因为Javascript没有Unicode正则表达式,所以我编写了一个Python程序来迭代整个Unicode并按Unicode名称进行过滤。手动实现这一点很困难。为什么不让计算机来完成这些肮脏和琐碎的工作呢

import unicodedata
import re
import sys

def unicodeNameMatch(pattern, codepoint):
  try:
    return re.match(pattern, unicodedata.name(unichr(codepoint)), re.I)
  except ValueError:
    return None

def regexChr(codepoint):
  return chr(codepoint) if 32 <= codepoint < 127 else "\\u%04x" % codepoint

names = sys.argv
prev = None

js_regex = ""
for codepoint in range(pow(2, 16)):
  if any([unicodeNameMatch(name, codepoint) for name in names]):
    if prev is None: js_regex += regexChr(codepoint)
    prev = codepoint
  else:
    if not prev is None: js_regex += "-" + regexChr(prev)
    prev = None

print "[" + js_regex + "]"

尝试
python char\u class.py“latin small”
可以为所有拉丁字母创建一个字符类

Edit:在正则表达式中出现
\u271d-\u271d
这一点上有一个小错误(也称为bug)。也许此修复程序有帮助:替换

if not prev is None: js_regex += "-" + regexChr(prev)


如果您必须坚持白名单,以下是最原始的方法:


它的工作原理是跟踪“所有”unicode字母字符。

这个正则表达式没有太多意义。你想表达什么?没错,负号应该在非法字符列表的开头。我已经更新了答案。黑名单不太好,因为有许多不需要的字符,例如控制代码,而且它不同我很难做到这一点。你真的应该只做白名单。是的,但我不知道javascript正则表达式中有任何字符类会包含所有特殊的国家字符。如果你想使用白名单,那么你可能应该使用外部库,如Tim Down的aswer。@nalply:白名单不太好,因为se有很多想要的字符,例如组合重音,很难做到这一点。你真的应该只做黑名单。@DietrichEpp,LOL。我提出了一个元编程解决方案来白名单所有内容。但是一个元编程解决方案来黑名单所有内容也会有意义。这是一个好的解决方案。它不适用于组合字符,试着用
n\u0303
替换
ñ
,你会发现它去除了重音。@DietrichEpp:没错。要处理这些情况,你只需将
\\p{incombindingDiacriticalMarks}
添加到正则表达式中即可。有关{Latin}的用法,请参见@TimDown+1感谢这一感谢,但似乎有些字符是失踪的。在本次感谢感谢这一感谢,但似乎有些人似乎有些字符是失踪的。在本次(0-9-9A-9A-9A-9A-9月的感谢这一感谢这一,但似乎有些人的这一感谢了这一次,但似乎有些人的一些字符似乎是有所有所失踪的。在本次(0-9-9-9-9-9-9-9-9-9-9-9-9-9-9-8-\u00d6\u00d6\u00d6\UU006\u00f6\U006\UUU006\UUU006\UUU006\UUUU00F6-8-8-8-8-8-6\U006\UU006\u00f6-6\UUU006\UUU006\UUUUUUUUUUUU006-6\UU-\ ua7ff\ufb00-\ufb06]+$/.测试返回false。这是一个用于拉丁字母(和阿拉伯数字)的字符类。难怪阿拉伯文本不匹配。我的错!我错过了。无论如何,我不会识别阿拉伯数字和非数字。:(请尝试
python char\u class.py“阿拉伯字母“
获取仅用于阿拉伯语字母的字符类。如果这不能满足您的需要,请查看Unicode字符数据库(请参阅上面的链接),例如
0620;阿拉伯文字母克什米尔YEH;Lo;0;AL;;;N;;
。python字符类生成器查看第二个字段,例如
阿拉伯文字母克什米尔YEH
,如果参数与包含的字段匹配。
0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;
if not prev is None: js_regex += "-" + regexChr(prev)
if not prev is None and prev != codepoint: js_regex += "-" + regexChr(prev)