用一个空格替换所有非字母数字字符、换行符和多个空格。

200

我正在寻找一个整洁的正则表达式解决方案,用于替换:

  • 所有非字母数字字符
  • 所有换行符
  • 所有多个空格的实例

用单个空格替换


对于那些在家里玩的人(以下方法有效

text.replace(/[^a-z0-9]/gmi, " ").replace(/\s+/g, " ");

我认为正则表达式可能已经足够强大了,可以用一条语句实现这个目标。我认为需要的组件是:

  • [^a-z0-9] - 用于删除非字母数字字符
  • \s+ - 匹配任何空格集合
  • \r?\n|\r - 匹配所有换行符
  • /gmi - 全局,多行,不区分大小写

然而,我似乎无法以正确的方式编写这个正则表达式(以下内容不起作用)。

text.replace(/[^a-z0-9]|\s+|\r?\n|\r/gmi, " ");

输入

234&^%,Me,2 2013 1080p x264 5 1 BluRay
S01(*&asd 05
S1E5
1x05
1x5

期望的输出

234 Me 2 2013 1080p x264 5 1 BluRay S01 asd 05 S1E5 1x05 1x5

你的尝试具体是怎样失败的?出了什么问题? - Pointy
10个回答

337

检查并测试它,我在js-regex方面没有太多经验 :p 很高兴你喜欢它。 - Jonny 5
10
请注意,\W 也会将非拉丁字符识别为非单词字符。 - webketje
3
我在这么多年后将这个答案标记为正确,因为我回顾了一下,发现被接受的答案没有排除下划线。 - TheGeneral

151

Jonny 5比我更快,我本来想建议使用\W+而不是\s, 如下所示:text.replace(/\W+/g, " ")。这样可以覆盖空白字符。


感谢 @T-CatSan 指出这一点!已加上,Saruman,你可以更改最佳答案为任何答案 :-) 但应该是 \W+,而不是 [W+]。祝大家新年快乐! - Jonny 5
谢谢,@Jonny5!我已经做了你建议的改变。之前我已经试过使用括号,现在看来不用也可以。祝你新年快乐。 - T-CatSan
1
嘿@T-CatSan,有没有办法添加异常?我想保留字符&-。有什么建议吗? - Renato Gama
1
我对/(\W+)|(_)/g进行了以下更改,以忽略下划线。但是我想知道为什么第一个模型没有忽略它,而且我的正则表达式是否高效。 - Sridhar Gudimela

20

由于[^a-z0-9]字符类包含所有非字母数字字符,因此它也包含空格字符!

 text.replace(/[^a-z0-9]+/gi, " ");

好的并且可用 - yigitt

9

我认为您只需要为每个模式添加限定符。此外,回车符的问题有点有趣:

text.replace(/[^a-z0-9]+|\s+/gmi, " ");
< p > < em >编辑 \s 表示匹配 \r\n

是的,那里有一些从其他关于这个主题的答案中获取的愚蠢行为,不过它很好用,谢谢! - TheGeneral

7

当 Unicode 参与其中时使用

text.replace(/[^\p{L}\p{N}]+/gu," ");

说明

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  [^\p{L}\p{N}]+           Any character except Unicode letters and digits
                           (1 or more times (matching the most amount possible))

JavaScript 代码片段:

const text = `234&^%,Me,2 2013 1080p x264 5 1 BluRąy
S01(*&aśd 05
S1E5
1x05
1x5`
console.log(text.replace(/[^\p{L}\p{N}]+/gu, ` `))


6

更新

请注意,浏览器环境变化迅速,这些基准测试可能已经过时且可能会误导读者。


这是我以前的一篇文章,其他答案大部分都还不错。但是我决定对每个解决方案进行基准测试,以及另一个显而易见的方法(只是为了好玩)。我想知道在不同大小的字符串和不同浏览器上的正则表达式模式之间是否有差异。

所以,我基本上使用了 jsPerf 来进行测试

  • 在 Chrome 65.0.3325 / Windows 10 0.0.0 上测试
  • 在 Edge 16.16299.0 / Windows 10 0.0.0 上测试

我测试的正则表达式模式是

  • /[\W_]+/g
  • /[^a-z0-9]+/gi
  • /[^a-zA-Z0-9]+/g

我用随机字符长度的字符串来测试它们

  • 长度为 5000
  • 长度为 1000
  • 长度为 200

我使用的示例 JavaScript 代码是 var newstr = str.replace(/[\W_]+/g," ");

每次运行包括每个正则表达式的 50 个或更多样本,并在每个浏览器上运行它们 5 次。

让我们比比看!

结果

                                Chrome                  Edge
Chars   Pattern                 Ops/Sec     Deviation   Op/Sec      Deviation
------------------------------------------------------------------------
5,000   /[\W_]+/g                19,977.80  1.09         10,820.40  1.32
5,000   /[^a-z0-9]+/gi           19,901.60  1.49         10,902.00  1.20
5,000   /[^a-zA-Z0-9]+/g         19,559.40  1.96         10,916.80  1.13
------------------------------------------------------------------------
1,000   /[\W_]+/g                96,239.00  1.65         52,358.80  1.41
1,000   /[^a-z0-9]+/gi           97,584.40  1.18         52,105.00  1.60
1,000   /[^a-zA-Z0-9]+/g         96,965.80  1.10         51,864.60  1.76
------------------------------------------------------------------------
  200   /[\W_]+/g               480,318.60  1.70        261,030.40  1.80
  200   /[^a-z0-9]+/gi          476,177.80  2.01        261,751.60  1.96
  200   /[^a-zA-Z0-9]+/g        486,423.00  0.80        258,774.20  2.15

事实上,无论是在浏览器中还是其他地方,正则表达式的差异性都很小。但是,如果再多运行几次,结果可能会更加清晰一些(但改善程度不会太大)。

一个字符的理论缩放

                            Chrome                        Edge
Chars   Pattern             Ops/Sec     Scaled            Op/Sec    Scaled
------------------------------------------------------------------------
5,000   /[\W_]+/g            19,977.80  99,889,000       10,820.40  54,102,000
5,000   /[^a-z0-9]+/gi       19,901.60  99,508,000       10,902.00  54,510,000
5,000   /[^a-zA-Z0-9]+/g     19,559.40  97,797,000       10,916.80  54,584,000
------------------------------------------------------------------------

1,000   /[\W_]+/g            96,239.00  96,239,000       52,358.80  52,358,800
1,000   /[^a-z0-9]+/gi       97,584.40  97,584,400       52,105.00  52,105,000
1,000   /[^a-zA-Z0-9]+/g     96,965.80  96,965,800       51,864.60  51,864,600
------------------------------------------------------------------------

  200   /[\W_]+/g           480,318.60  96,063,720      261,030.40  52,206,080
  200   /[^a-z0-9]+/gi      476,177.80  95,235,560      261,751.60  52,350,320
  200   /[^a-zA-Z0-9]+/g    486,423.00  97,284,600      258,774.20  51,754,840

我不会太关注这些结果,因为这并不是显著差异,我们只能看出Edge比较慢。另外,我当时非常无聊。
总之,您可以自行运行基准测试。 在这里查看Jsperf基准测试

这似乎与OP的查询完全无关。 - kevinc

4

我看到了另一篇也有变音符的帖子,这很好。

s.replace(/[^a-zA-Z0-9À-ž\s]/g, "")


3
要使用破折号替换,请执行以下操作:
text.replace(/[\W_-]/g,' ');

1

对于仍在苦苦挣扎的人(像我一样...)在上面专家回复后,这在Visual Studio 2019中有效:

outputString = Regex.Replace(inputString, @"\W", "_");

记得添加。
using System.Text.RegularExpressions;

0
const processStirng = (str) => (
    str
    .replace(/[^a-z0-9\s]/gi, '') // remove all but alpha-numeric and spaces
    .replace(/ +/g, ' '); // remove duplicated spaces
);
processSting(' $ your    string    here #');

虽然这段代码可能回答了问题,但提供关于为什么和/或如何回答问题的附加上下文可以提高其长期价值,并帮助原帖作者和其他人理解其背后的逻辑。 - stelioslogothetis

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