正则表达式使用踩坑

前几天在XX工具中使用正则表达式匹配一些字符串,一开始匹配的字符串都是英文的,没有啥问题,后续需求变更,需要匹配一些中文字符,结果就出问题了。

比如我要匹配{月:1},按照一开始的想法觉着这不简单吗?直接这样写不就完事了

C#
var value="{月:1}";
var matcher=Regex.Matches(value,@"\{(?<type>month|月):(?<date>-{0,1}\d{1,3})\}");

结果你发现怎么都无法匹配成功,一旦涉及到中文字符,就会出现这个问题,所以就意识到这个可能涉及到字符编码的问题,后来去网上一搜,很多文章都提到这样的说法

在C#中,匹配中文的正则表达式用Unicode来表示时,范围是: [\u4e00-\u9fa5]。

于是按照下面的这个写法就没有问题了

C#
var value="{月:1}";
var matcher=Regex.Matches(value,@"\{(?<type>month|\u6708:(?<date>-{0,1}\d{1,3})\}");

然后,又遇到一个问题,如果涉及到要匹配两个中文字符怎么办?以上是匹配一个中文字符,是可以匹配的,那么两个中文字符这么写就不行了,于是针对有两个中文字符的匹配规则就改成这样

C#
var value="{record:1}{记录:1}";
var matcher=Regex.Matches(value,@"\{(record|\u8bb0\u5f55)[:\uff1a]{1}(?<date>-{0,1}\d{1,3})\}");

备注

如果涉及到中文的标点符号,也需要注意编码的问题

等等,似乎我们忘记了什么?

对,既然这是一个python博客,怎么少得了关于python匹配正则表达式的问题呢?那python是否会出现类似的情况?

目前测试的结果是:不会,也就是不需要转成Unicode就可以匹配,测试代码如下

Python
import re
print(re.findall("\{(month|年):(-{0,1}\d{1,3})\}",r"{month:1}"))
print(re.findall("\{(month|年):(-{0,1}\d{1,3})\}",r"{年:1}"))
# [('month', '1')]
# [('年', '1')]

那怎么把汉字转换成Unicode字符呢?经过测试下面的代码可以使用

C#
public string GetUnicode(string text)
{
    string result = "";
    for (int i = 0; i < text.Length; i++)
    {
        if ((int)text[i] > 32 && (int)text[i] < 127)
        {
            result += text[i].ToString();
        }
        else
            result += string.Format("\\u{0:x4}", (int)text[i]);
    }
    return result;
}