用正则表达式删除中文单词之间的所有空格

Nee*_*ell 40 javascript regex

我想删除中文文本中的所有空格.

我的文字: "? ? ? ? ? 10 ? ? ? ? ?. Can you help me?"

理想输出: "????? 10 ?????. Can you help me?"

var str = '? ? ? ? ? 10 ? ? ? ? ?. Can you help me?';
str = str.replace("/\ /", "");
Run Code Online (Sandbox Code Playgroud)

我已经研究了类似的Python问题,但它似乎不能在我的情况下工作,所以我在这里提出了一些问题的帮助.

Wik*_*żew 30

进入中文字符匹配模式

使用Unicode工具,\p{Han}可以将与任何中文字符匹配的Unicode属性类转换为

[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FEF\uF900-\uFA6D\uFA70-\uFAD9\U00020000-\U0002A6D6\U0002A700-\U0002B734\U0002B740-\U0002B81D\U0002B820-\U0002CEA1\U0002CEB0-\U0002EBE0\U0002F800-\U0002FA1D]
Run Code Online (Sandbox Code Playgroud)

在ES6中,为了匹配单个中文字符,它可以用作

/[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FEF\uF900-\uFA6D\uFA70-\uFAD9\u{20000}-\u{2A6D6}\u{2A700}-\u{2B734}\u{2B740}-\u{2B81D}\u{2B820}-\u{2CEA1}\u{2CEB0}-\u{2EBE0}\u{2F800}-\u{2FA1D}]/u
Run Code Online (Sandbox Code Playgroud)

使用ES2015 Unicode正则表达式转换器将它映射到ES5 ,我们得到

(?:[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FEF\uF900-\uFA6D\uFA70-\uFAD9]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D])
Run Code Online (Sandbox Code Playgroud)

使用JS匹配任何中文字符的模式RegExp.

所以,你可以使用

s.replace(/([\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FEF\uF900-\uFA6D\uFA70-\uFAD9]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D])\s+(?=(?:[\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DB5\u4E00-\u9FEF\uF900-\uFA6D\uFA70-\uFAD9]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]))/g, '$1')
Run Code Online (Sandbox Code Playgroud)

请参阅正则表达式演示.

如果您的JS环境符合ECMAScript 2018标准,则可以使用更短的

s.replace(/(\p{Script=Hani})\s+(?=\p{Script=Hani})/gu, '$1')
Run Code Online (Sandbox Code Playgroud)

图案细节

  • (CHINESE_CHAR_PATTERN)- 捕获第1组($1替换模式):任何中文字符
  • \s+ - 任何1+空格(任何Unicode空格)
  • (?=CHINESE_CHAR_PATTERN) - 当前位置右侧必须有中文字符.

JS演示:

var s = "? ? ? ? ? 10 ? ? ? ? ?. Can you help me?";
var HanChr = "[\\u2E80-\\u2E99\\u2E9B-\\u2EF3\\u2F00-\\u2FD5\\u3005\\u3007\\u3021-\\u3029\\u3038-\\u303B\\u3400-\\u4DB5\\u4E00-\\u9FEF\\uF900-\\uFA6D\\uFA70-\\uFAD9]|[\\uD840-\\uD868\\uD86A-\\uD86C\\uD86F-\\uD872\\uD874-\\uD879][\\uDC00-\\uDFFF]|\\uD869[\\uDC00-\\uDED6\\uDF00-\\uDFFF]|\\uD86D[\\uDC00-\\uDF34\\uDF40-\\uDFFF]|\\uD86E[\\uDC00-\\uDC1D\\uDC20-\\uDFFF]|\\uD873[\\uDC00-\\uDEA1\\uDEB0-\\uDFFF]|\\uD87A[\\uDC00-\\uDFE0]|\\uD87E[\\uDC00-\\uDE1D]"; 
console.log(s.replace(new RegExp('(' + HanChr + ')\\s+(?=(?:' + HanChr + '))', 'g'), '$1'));
Run Code Online (Sandbox Code Playgroud)

符合ECMAScript 2018标准的正则表达式测试:

var s = "? ? ? ? ? 10 ? ? ? ? ?. Can you help me?";
console.log(s.replace(/(\p{Script=Hani})\s+(?=\p{Script=Hani})/gu, '$1'));
Run Code Online (Sandbox Code Playgroud)

  • @ Pac0那是因为`/(\ p {Script = Hani})\ s +(?=\p {Script = Hani})/ gu`,FF不支持ECMAScript 2018 Unicode属性类.Chrome确实如此. (2认同)

Gré*_*EUT 21

使用@Brett Zamir解决方案如何在正则表达式中匹配中文字符

Javascript unicode字符串,中文字符但没有标点符号


const str = '? ? ? ? ? 10 ? ? ? ? ?. Can you help me?';

const regex = new RegExp('([\u4E00-\u9FCC\u3400-\u4DB5\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d]) ([\u4E00-\u9FCC\u3400-\u4DB5\uFA0E\uFA0F\uFA11\uFA13\uFA14\uFA1F\uFA21\uFA23\uFA24\uFA27-\uFA29]|[\ud840-\ud868][\udc00-\udfff]|\ud869[\udc00-\uded6\udf00-\udfff]|[\ud86a-\ud86c][\udc00-\udfff]|\ud86d[\udc00-\udf34\udf40-\udfff]|\ud86e[\udc00-\udc1d])* ', 'g');

const ret = str.replace(regex, '$1$2');

console.log(ret);
Run Code Online (Sandbox Code Playgroud)


看起来像 :

([foo chinese chars]) ([foo chinese chars])*
Run Code Online (Sandbox Code Playgroud)

  • 此处的输出与理想输出不匹配.注意10前面的空间. (2认同)
  • @GrégoryNEUT`blabla`不是一个常见的[metasyntactic变量](https://en.wikipedia.org/wiki/Metasyntactic_variable)英文,你可能想用`foo`代替;) (2认同)
  • 当在其他文本之前存在偶数个汉字时,这个答案不起作用,例如@bobblebubble提到:`请的10多个a`.在这种情况下,它将删除太多空格. (2认同)

Pus*_*shi 9

中文字符的范围可以写成,[\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]因此您可以使用此正则表达式选择中文字符和空格,并确保通过此前瞻后面跟着中文字符(?=[\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]+),

([\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]+)\s+(?=[\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]+)
Run Code Online (Sandbox Code Playgroud)

并替换它 $1

演示

var str = '? ????? ? ????? ? 10 ???? ? ? ? ?. Can you help me?';
console.log(str.replace(/([\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]+)\s+(?=[\u2E80-\u2FD5\u3190-\u319f\u3400-\u4DBF\u4E00-\u9FCC]+)/g, "$1"));
Run Code Online (Sandbox Code Playgroud)