JavaScript正则表达式:从DOM ID中删除非法字符

17
我有许多DOM元素在网页上动态创建。它们的ID是从外部列表生成的,有时这些名称可能包含ID的非法字符,如"@"或"&"。
我需要删除不符合以下规则的字符:
- 字符串必须以字母开头 - 第一个字符后可以跟随任意数量的字母、数字([0-9])、连字符(“-”)、下划线(“_”)、冒号(“:”)和句点(“.”)
因此,如果原始字符串为:
99% of People are not the 1%
那么删除非法字符后的结果字符串将是:
ofPeoplearenotthe1
谁能帮我编写JavaScript中的正则表达式,以删除不符合上述要求的字符串中的字符?

2
你的意思是应该写成 ofPeoplearenotthe1 吗? - Qtax
你说得完全正确。我已经更新了问题。 - user330366
6个回答

36
var str = "99% of People are not the 1%";
str = str.replace(/^[^a-z]+|[^\w:.-]+/gi, "");

6
请注意,ID(标识符)也必须是唯一的。如果您要删除非法字符以遵守标准,则还需要维护一个“已使用”的ID列表,以便避免冲突。 - Matt
3
@umair.ali,基本上是一样的,可以这样引用:@"(?i:^[^a-z]+|[^\w:.-]+)" - Qtax
我该如何在不替换空格的情况下实现?就像这样:of People are not the 1 - Squirrl
2
这似乎没有从ID中删除句点?不确定是否符合HTML规范;但它确实防止JQuery使用ID选择器访问元素。最终我使用了这个 str.replace(/^[^a-z]+|[^\w]+/gi, "") - JeffryHouser
3
接受的答案在不必要的情况下使用了 i 标志,这可能会增加正则表达式的运行时间。更具体(因此更有效)的正则表达式是:str = str.replace(/^[^a-zA-Z]+|[^\w:.-]+/g, ""); 该正则表达式可以更高效地完成任务。 - Nadav
显示剩余3条评论

2
HTML5规范已更新,根据https://html.spec.whatwg.org/multipage/dom.html#global-attributesid属性现在可以包含除空格以外的任何字符。

当在HTML元素上指定时,id属性值必须在元素树中唯一,并且必须至少包含一个字符。该值不得包含任何ASCII空格。

我不确定元素何时能够分配两个id属性,也不知道其逻辑目标(可能是因为当时理解不够成熟),但是这已被从标准中删除,然而这在Web开发社区中已经是常识了多年。

1
我认为规范中提到的“唯一性”并不是指将两个ID分配给一个元素的可能性。而是要求ID在DOM树内是唯一的,以便它能够发挥其主要作用:帮助识别和引用元素。在大多数情况下,类就足够了(而且通常更灵活)。但是还有一种情况需要使用ID,那就是通过标签的“for”属性连接表单字段输入和标签的示例:` - mwld

2
如果您想要一个抗冲突的选项,可以尝试使用 btoa 转换为 base64 编码;
var badId1 = "99% of the 1%";
var badId2 = "999% of the 1%";
var validId1 = "ID_OTklIG9mIHRoZSAxJQ";
var validId2 = "ID_OTk5JSBvZiB0aGUgMS";

var makeId = function(text) { return "ID_" + btoa(text).slice(0,-2); }; 

expect(makeId(badId1)).toEqual(validId1);
expect(makeId(badId2)).toEqual(validId2);

注意这两个 IDS 生成不同的键,而正则表达式修剪则不会。


1
如果有人需要用Java实现这个功能:
    if(! htmlId.matches("^[A-Za-z0-9]+[\\w\\-\\:\\.]*$")){
        LOG.warn("html id "+htmlId+" is not valid, have to remove all invalid chars");

        htmlId = htmlId.replaceAll("[^^A-Za-z0-9\\w\\-\\:\\.]+", "");
    }

在我的情况下,我检查了字符串,并用空白替换了所有无效的内容。感谢Qtax。

1
var id = "99% of People are not the 1%";
id = id.replace(/[^a-z0-9\-_:\.]|^[^a-z]+/gi, "");

演示:http://jsfiddle.net/jfriend00/qqjh6/

思路是先替换一个或多个非字母字符,然后再替换剩余字符串中的所有非法字符。

有人可能会问,如果ID是根据内容动态生成的,并且事先不知道,那么它的意义是什么?如果基于某些可能发生变化的内容,您肯定无法在CSS中使用它。


这将输出“9ofPeoplearenotthe1”,ID不能以数字开头。 - gen_Eric
@Rocket - 你太快了。在你发表评论之前,它已经被编辑以修正那个问题了。 - jfriend00
我今天非常快,可能跟我喝了太多咖啡有关。 - gen_Eric
@umair.ali - 抱歉,我不懂C#。 - jfriend00

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接