正则 \s 不同语言的差异 \u0020 \u00A0 快来入坑吧😂

2020-04-08 02:54:46 +08:00
 xiangyuecn

mark 一下,稍不留神就要坑死人😂 而且是半天摸不清楚原因😂

❌java:

System.out.println(Pattern.compile("^\\s+$").matcher("\u0020\u00A0").find());

👌python3:

import re;print(re.search('^\s+$', u'\u0020\u00A0'))

❌python2:

import re;print(re.search('^\s+$', u'\u0020\u00A0'))

👌C#:

System.Console.WriteLine(new Regex("^\\s+$").IsMatch("\u0020\u00A0"))

👌js:

/^\s+$/.test("\u0020\u00A0")

难搞啊。。。ASCII space 。。。Unicode separator

2087 次点击
所在节点    程序员
5 条回复
sakila
2020-04-08 08:31:22 +08:00
关于这个问题你可以看一下字符的类别, `unicodedata.category(unichr)`可以返回 str 的常规类别([general category]( https://en.wikipedia.org/wiki/Unicode_character_property)). 比如中文或一些外文的的声调符号的 category 是`Mn`.

`unicodedata.normalize(form, unistr)`可以返回 Unicode 字符串 unistr 的普通形式“form”, 有`NFC`, `NFKC`, `NFD`和`NFKD`等, 详细解释见[unicode equivalence]( https://en.wikipedia.org/wiki/Unicode_equivalence)

比如一段代码:

```python
>>> s = 'Ślusàrski'
>>> print(s)
'Ślusàrski'
```

现在是 NFC composition 形式, 也就是'Ś' = 'Ś'

转换成 NFD decomposition 形式:

```python
>>> print(ascii(unicodedata.normalize('NFD','Ślusàrski')))
'S\u0301lusa\u0300rski'
```

'Ś' = 'S\u0301'

因此可以写一个 unicode_to_ascii 的函数:

>>> s = 'Ślusàrski'
>>> def unicode_to_ascii(s):
>>> return ''.join(c for c in unicodedata.normalize('NFD', s)
>>> if unicodedata.category(c) != 'Mn')
>>> print(unicode_to_ascii(s))
Slusarski
```

不知道是否满足题主的问题
sakila
2020-04-08 08:31:55 +08:00
回复不能用 markdown?? 题主将就看吧
fzhyzamt
2020-04-08 09:57:56 +08:00
Java
System.out.println(Pattern.compile("\\p{javaSpaceChar}").matcher("\u0020\u00A0").find());

Python2
print(re.search('^\s+$', u'\u0020\u00A0', flags=re.UNICODE))
onecode
2020-04-08 10:21:02 +08:00
对于我这种正则菜鸟来说,用了正则一个 bug 变两个 bug
xiangyuecn
2020-04-08 11:03:36 +08:00
@sakila @fzhyzamt 哈哈,你们的处理方法都没毛病。

我这个帖子其实是想表达\s 在不同语言下直接使用可能会有问题,需要留意;比如 js 里面用的好好的,直接 copy 到 java 里面可能就不能用了,需要针对各自语言学习各自的特殊处理方案,使用成本急剧增加。

本来我以为那种非常简单的正则表达式在哪都通用的,没想到不是😁 出现'\u00A0'目前接触到的比较多的还是网页内 html 编辑器 js 插入的连续空白,人工输入基本上不太可能会输入'\u00A0',但 js 最终获取编辑的内容时,如果没有把空格替换回来就会在最终贴子里面出现'\u00A0'字符(比如:微信支付的文档)。好像不同浏览器对'\u00A0'的解析显示也是有差异的,蛋疼

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/660288

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX