起因:
在开发过程中,需要对字符串进行替换过滤,首先考虑到的是replace函数,这个函数是比较通用的替换函数,str.Trim().Replace("某字符串", "")
即可全部替换字符串,但是在这次的特殊情况下,是需要替换特殊情景的字符串,就想到了正则表达式
正则表达式:
又名 “规则表达式”,由我们自己来书写 “规则”,专门用来检测字符串是否符合 “规则” 使用的,我们使用一些特殊的字符或者符号定义一个 “规则公式”,然后用我们定义好的 “规则公式” 去检测字符串
简单的示例:
var reg = /\d+/ // \d是检测数字 +是表示任意多个
var str1 = '123456'
var str2 = 'abcdef'
console.log(reg.test(str1)) // 返回true
console.log(reg.test(str2)) // 返回false
首先是正则表达式中最基础的元字符
.
: 匹配非换行的任意字符
\s
: 匹配空白字符(空格/制表符/...)
\S
: 匹配非空白字符
\d
: 匹配数字
\D
: 匹配非数字
\w
: 匹配数字字母下划线
\W
: 匹配非数字字母下划线
*
: 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,}
x|y
: 匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"
+
: 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
^
: 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置
$
: 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置
[abc]
: 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a',加入^
可以表示非集合,如[^abc]
表示不是abc
\
: 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\' 匹配 "" 而 "(" 则匹配 "("
?
: 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 。? 等价于 {0,1}。当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。
{n,m}
: m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。注意在逗号和两个数之间不能有空格,且m可以为空,意为无穷大
(pattern)
: 匹配 pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 9 属性。要匹配圆括号字符,请使用 '(' 或 ')'。
(?:pattern)
: 正向肯定预查(look ahead positive assert),在任何匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,"Windows(?=95|98|NT|2000)"能匹配"Windows2000"中的"Windows",但不能匹配"Windows3.1"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
(?!pattern)
: 正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如"Windows(?!95|98|NT|2000)"能匹配"Windows3.1"中的"Windows",但不能匹配"Windows2000"中的"Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
正则表达式 - 运算符优先级
运算符 | 描述 |
---|---|
\ |
转义符 |
(), (?:), (?=), [] |
圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m} |
限定符 |
^, $, \ 任何元字符、任何字符 |
定位点和序列(即:位置和顺序) |
| |
替换,"或"操作字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood" |
实例:
回到正题我是为了匹配替换一个字符串使用了正则表达式,一般的替换只是用通用的replace即可:
If str.Trim.Contains("""") Then
message.To.Add(New MailAddress(str.Trim().Replace("""", "")))
Else
message.To.Add(New MailAddress(str.Trim()))
End If
但是如果是只替换某些特殊情况下的字符,如下面我需要替换名称中间的英文逗号为英文句号
“Tom, Striy”<11123@163.com>,”Ben, Rop”<11123@163.com>,”Rick, City”<11123@163.com>
则可以按照(英文双引号)(任意长度中英文字符串)(英文逗号)(空格)(任意长度中英文字符串)(英文双引号)
这个规则来对字符串中名称中间的逗号进行匹配
写出正则表达式为 (\u0022)([a-zA-Z\u4e00-\u9fa5]+),(\s[a-zA-Z\u4e00-\u9fa5]+)(\u0022)
,放入代码中使用则如下:
If Regex.Matches(str.Trim(), "(\u0022)([a-zA-Z\u4e00-\u9fa5]+),(\s[a-zA-Z\u4e00-\u9fa5]+)(\u0022)").Count > 0 Then
str = Regex.Replace(str.Trim(), "(\u0022)([a-zA-Z\u4e00-\u9fa5]+),(\s[a-zA-Z\u4e00-\u9fa5]+)(\u0022)", "$1$2.$3$4")
End If
正则表达式测试工具
这里我推荐在写正则表达式的适合使用一下测试工具进行测试,能够减少出错的可能性,如下图我就可以对我写的正则表达式进行测试:
附录:
常用的正则表达式
PS:此处的校验数字的表达式和校验字符的表达式总结参考自CSDN博主「ZhaoYingChao88」的原创文章
一、校验数字的表达式
1. 数字:^[0-9]*$
2. n位的数字:^\d{n}$
3. 至少n位的数字:^\d{n,}$
4. m-n位的数字:^\d{m,n}$
5. 零和非零开头的数字:^(0|[1-9][0-9]*)$
6. 非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
7. 带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
8. 正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
9. 有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
10. 有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
11. 非零的正整数:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
12. 非零的负整数:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
13. 非负整数:^\d+$ 或 ^[1-9]\d*|0$
14. 非正整数:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
15. 非负浮点数:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
16. 非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
17. 正浮点数:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
18. 负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
19. 浮点数:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
二、校验字符的表达式
1. 汉字:^[\u4e00-\u9fa5]{0,}$
2. 英文和数字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
3. 长度为3-20的所有字符:^.{3,20}$
4. 由26个英文字母组成的字符串:^[A-Za-z]+$
5. 由26个大写英文字母组成的字符串:^[A-Z]+$
6. 由26个小写英文字母组成的字符串:^[a-z]+$
7. 由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
8. 由数字、26个英文字母或者下划线组成的字符串:^\w+$ 或 ^\w{3,20}$
9. 中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
10. 中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
11. 可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+ 12 禁止输入含有~的字符:[^~\x22]+
其它:
.*匹配除 \n 以外的任何字符。
/[\u4E00-\u9FA5]/ 汉字
/[\uFF00-\uFFFF]/ 全角符号
/[\u0000-\u00FF]/ 半角符号