面试题——正则表达式


简介

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

在线测试网站:点我进入

在线练习网站:点我进入正则表达式

基础

元字符

代码说明
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
^匹配字符串的开始
$匹配字符串的结束
\b元字符通常用于查找位于单词的开头或结尾的匹配

重复

代码说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次

字符类
但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办?
很简单,你只需要在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)。
我们也可以轻松地指定一个字符范围,像[0-9]代表的含意与\d就是完全一致的:一位数字;同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)。
分枝条件
用|把不同的规则分别表达。
如:0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。
反义

代码说明
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

分组
重复单个字符直接在字符后面加上限定符就行了,但如果想要重复多个字符又该怎么办?你可以用小括号来指定子表达式(也叫做分组),然后你就可以指定这个子表达式的重复次数了,你也可以对子表达式进行其它一些操作。
使用小括号指定一个子表达式后,匹配这个子表达式的文本(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。捕获组可以通过从左到右计算其开括号来编号。例如,在表达式 ((A)(B©)) 中,存在四个这样的组:

  1. ((A)(B©))
  2. (A)
  3. (B©)
  4. ©

组零始终代表整个表达式。
之所以这样命名捕获组是因为在匹配中,保存了与这些组匹配的输入序列的每个子序列。捕获的子序列稍后可以通过 Back 引用在表达式中使用,也可以在匹配操作完成后从匹配器获取。

与组关联的捕获输入始终是与组最近匹配的子序列。如果由于量化的缘故再次计算了组,则在第二次计算失败时将保留其以前捕获的值(如果有的话)例如,将字符串 “aba” 与表达式 (a(b)?)+ 相匹配,会将第二组设置为 “b”。在每个匹配的开头,所有捕获的输入都会被丢弃。

以 (?) 开头的组是纯的非捕获 组,它不捕获文本,也不针对组合计进行计数。

后向引用用于重复搜索前面某个分组匹配的文本。例如:
\b(\w+)\b\s+\1\b可以用来匹配重复的单词,像go go, 或者kitty kitty。

也可以自己指定子表达式的组名。要指定一个子表达式的组名,请使用这样的语法:(?\w+)(或者把尖括号换成’也行:(?‘Word’\w+)),这样就把\w+的组名指定为Word了。要反向引用这个分组捕获的内容,你可以使用\k,所以上一个例子也可以写成这样:\b(?\w+)\b\s+\k\b。

零宽断言

(?=exp)也叫零宽度正预测先行断言,它断言被匹配的字符串以表达式exp结尾但除了结尾以外的部分。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I’m singing while you’re dancing.时,它会匹配sing和danc。
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

代码说明
(?=exp)匹配exp前面的位置
(?<=exp)匹配exp后面的位置
(?!exp)匹配后面跟的不是exp的位置
(?<!exp)]匹配前面不是exp的位置

注释
小括号的另一种用途是通过语法(?#comment)来包含注释。例如:

2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d \d?(?#0-199)

贪婪与懒惰

代码说明
*?重复任意次,但尽可能少重复
+?重复1次或更多次,但尽可能少重复
??重复0次或1次,但尽可能少重复
{n,m}?重复n到m次,但尽可能少重复
{n,}?重复n次以上,但尽可能少重复

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可
能多的字符。考虑这个表达式:a.b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的
话,它会匹配整个字符串aabab。这被称为贪婪匹配。
有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,
只要在它后面加上一个问号?。这样.
?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用
最少的重复。现在看看懒惰版的例子吧:
a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字
符)和ab(第四到第五个字符)。

POSIX 字符类(仅 US-ASCII)

语法说明
\p{Lower}小写字母字符:[a-z]
\p{Upper}大写字母字符:[A-Z]
\p{ASCII}所有 ASCII:[\x00-\x7F]
\p{Alpha}字母字符:[\p{Lower}\p{Upper}]
\p{Digit}十进制数字:[0-9]
\p{Alnum}字母数字字符:[\p{Alpha}\p{Digit}]
\p{Punct}标点符号:!"#$%&’()*+,-./:;<=>?@[]^_{\
\p{Graph}可见字符:[\p{Alnum}\p{Punct}]
\p{Print}可打印字符:[\p{Graph}\x20]
\p{Blank}空格或制表符:[ \t]
\p{Cntrl}控制字符:[\x00-\x1F\x7F]
\p{XDigit}十六进制数字:[0-9a-fA-F]
\p{Space}空白字符:[ \t\n\x0B\f\r]

引用

语法说明
\Nothing,但是引用以下字符
\QNothing,但是引用所有字符,直到 \E
\ENothing,但是结束从 \Q 开始的引用

如:\Q\w+\E表示字符串\w+而不是正则中的单词字符:[a-zA-Z_0-9]。

其他

语法说明
\xhh十六进制值为0xhh的字符
\uhhhh 十六进制表示为0xhhhh的Unicode字符
\t制表符Tab
\n换行符
\r回车
\f换页
\e转义(Escape)

处理选项
上面介绍了几个选项如忽略大小写,处理多行等,这些选项能用来改变处理正则表达式的方式。下面是Java中常用的正则表达式选项:

名称说明
CASE_INSENSITIVE匹配时区分大小写
MULTILINE更改^和 的 含 义 , 使 它 们 分 别 在 任 意 一 行 的 行 首 和 行 尾 匹 配 , 而 不 仅 仅 在 整 个 字 符 串 的 开 头 和 结 尾 匹 配 。 ( 在 此 模 式 下 , 的含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。(在此模式下, 使(,的精确含意是:匹配\n之前的位置以及字符串结束前的位置.)
DOTALL在 dotall 模式中,表达式 . 可以匹配任何字符,包括行结束符。默认情况下,此表达式不匹配行结束符。
UNICODE_CASE指定此标志后,由 CASE_INSENSITIVE 标志启用时,不区分大小写的匹配将以符合
CANON_EQ启用规范等价。指定此标志后,当且仅当其完整规范分解匹配时,两个字符才可视为匹配。例如,当指定此标志时,表达式 “a\u030A” 将与字符串 “\u00E5” 匹配。默认情况下,匹配不考虑采用规范等价。不存在可以启用规范等价的嵌入式标志字符。指定此标志可能对性能产生影响。
UNIX_LINES启用 Unix 行模式。在此模式中,.、^ 和 $ 的行为中仅识别 ‘\n’ 行结束符。通过嵌入式标志表达式 (?d) 也可以启用 Unix 行模式。
LITERAL指定此标志后,指定模式的输入字符串就会作为字面值字符序列来对待。输入序列中的元字符或转义序列不具有任何特殊意义。标志 CASE_INSENSITIVE 和 UNICODE_CASE 在与此标志一起使用时将对匹配产生影响。其他标志都变得多余了。不存在可以启用字面值解析的嵌入式标志字符。
UNICODE_CHARACTER_CLASS
COMMENTS模式中允许空白和注释。此模式将忽略空白和在结束行之前以 # 开头的嵌入式注释。通过嵌入式标志表达式 (?x) 也可以启用注释模式。

JAVA里正则的基本用法

Pattern pattern = Pattern.compile("\\ba\\w*\\b");
Matcher matcher = pattern.matcher("abcdab cccabcd aaacd");
int index = 0;
while (matcher.find()) {
    String res = matcher.group();
    System.out.println(index + ":" + res);
    index++;
}

\\ba\\w*\\b表示匹配以字母a为开头的单词。
Pattern.compile(regex)表示将给定的正则表达式编译到具有给定标志的模式中。
matcher(str)创建匹配给定输入与此模式的匹配器。
mather.find()尝试查找与该模式匹配的输入序列的下一个子序列。
此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始。
如果匹配成功,则可以通过 start、endgroup 方法获取更多信息。
group()返回由以前匹配操作所匹配的输入子序列。

相关案例

切记:正则表达式匹配的是片段,是符合条件的某段字符串或几段字符串!

1、 给一个连字符串例如:get-element-by-id转化成驼峰形式。

var str = "get-element-by-id";
var reg = /-(\w)/g;
console.log(str.replace(reg, function(match, p1){
    return p1.toString().toUpperCase();
})); //getElementById
字符串的转为大写:toUpperCase();转为小写:toLowerCase()

2、匹配一个[1-255]的数字

括号内匹配符合条件的值都可以,但是要以匹配的括号内容开头且结尾。这样就不会匹配345中的34和5了。

var str = "248";
var reg = /^([1]\d\d|[2][0-4]\d|[2]5[0-5]|[1-9]\d|[1-9])$/
console.log(str.match(reg));

3、匹配ip地址

var str = "248.89.31.26";
var reg = /^(([1]\d\d|[2][0-4]\d|[2]5[0-5]|[1-9]\d|[1-9])\.){3}([1]\d\d|[2][0-4]\d|[2]5[0-5]|[1-9]\d|[1-9])$/
console.log(str.match(reg));

4、关于开头和结尾

开头^和结尾$运算符 的优先级只大于 或 |

开头或结尾运算符修饰的是整个正则,除非有或

比如:匹配以多个数字和m开头的片段

var str = "12346m";
var reg = /^\d+m/g;
console.log(str.match(reg)); //["12346m"]
比如:匹配以多个数字和m结尾的片段

var str = "12346m";
var reg = /\d+m$/g;
console.log(str.match(reg)); //["12346m"]
 再比如:匹配以多个数字和m开头,且以这个几个数字和这个m结尾!因为^$同时修饰的是匹配到的该片段!

var str = "12346m";
var reg = /^\d+m$/g;
console.log(str.match(reg)); //["12346m"]
如果有或|,匹配以多个数字开头的片段 或者 以m结尾的片段

var str = "12346m";
var reg = /^\d+|m$/g;
console.log(str.match(reg)); //["12346", "m"]
5、量词之间要用(),连着两个量词的正则表达式是错误的!

var reg = /\d{1,3}*/g

量词{1,3}后面再跟量词*将会报错!!!

6、子表达式嵌套子表达式,他们的先后顺序,谁是$1,谁又是$2

下面表达式reg1,(\d{1,3})是第一个子表达式;((\d{3})*)第二个子表达式;(\d{3})第三个子表达式。

特点:正则中,括号从左到右,从外到内

var str = "1234567890";
var reg1 = /^(\d{1,3})((\d{3})*)$/
var reg2 = /\d{3}/g
console.log(str.match(reg1))
var replaceStr = str.replace(reg1, function (match, p1, p2, p3) {
    return p1 + p2.replace(reg2, ",$&")
})
console.log(replaceStr);

7、子表达式后面跟有量词,最后一次匹配到的内容,作为子表达式的值

我们知道非全局匹配下的match方法的结果和exec方法的结果一样,会得到所有的匹配信息,包括子表达式的内容。

以下例子中,子表达式的值是456,匹配多个3数字,最后一个3数字的内容。

var str = "12345678";
var reg = /(\d{3})*/
console.log(str.match(reg))
["123456", "456", index: 0, input: "12345678", groups: undefined]

8、| 或情况下的子表达式可能是undefined

在或 | 的情况下,有的子表达式未匹配到内容,其值是undefined。

结果会有第二个子表达式的值,但值是undefined。如果继续往后面匹配,比如用exec多次执行往后匹配,当匹配b1的时候,第一个子表达式是undefined,而第二个子表达式是b1。

var str = "a1b1a2b2";
var reg = /(a\d)|(b\d)/
console.log(str.match(reg))
 
["a1", "a1", undefined, index: 0, input: "a1b1a2b2", groups: undefined]

9、如何让正则表达式匹配先匹配后面的片段,再匹配前面的片段

我们知道正则表达式是从字符串的前面开始匹配,即从左到右进行匹配寻找符合条件的片段,比如:

下面字符串“12345”,匹配连续的两个数字,会匹配到12 和 34;而不是 23 和45

var str = "12345";
var reg = /\d{2}/g
console.log(str.match(reg)); //["12", "34"]

如果就是想匹配23和45呢?我们必须使用$符,因为我们无法从右往左匹配,只能先把2345匹配出来,再进行匹配拆分:

var str = "12345";
var reg1 = /(\d{2})+$/g
var reg2 = /\d{2}/g;
console.log(str.match(reg1)[0].match(reg2)) // ["23", "45"]

10、关于$符,结尾的作用时的匹配匹配规则

没有$符时,\d{1,3}会先匹配三个数字,(\d{3})*再匹配三个数字。然后\d{1,3}再匹配剩下的78

var str = "12345678";
var reg = /\d{1,3}(\d{3})*/g
console.log(str.match(reg))  // ["123456", "78"]
 如果非全局匹配:也先匹配3个数字

var str = "12345678";
var reg = /\d{1,3}(\d{3})*/
console.log(str.match(reg))
 // ["123456", "456", index: 0, input: "12345678", groups: undefined]
如果有开头符号,也是先匹配3个数字

var str = "12345678";
var reg = /^\d{1,3}(\d{3})*/g
console.log(str.match(reg)) // ["123456"]
我们再来看看有$符时,\d{1,3}就会优先让(\d{3})*先匹配符合的数字,剩下的再由\d{1,3}匹配,这样\d{1,3}就不会先匹配了。

var str = "12345678";
var reg = /\d{1,3}(\d{3})*$/g
console.log(str.match(reg)) // ["12345678"]
匹配结果:["12345678"],345和678是(\d{3})*匹配到的,12是\d{1,3}匹配到的。

如果同时有开头符^和结束符KaTeX parse error: Undefined control sequence: \d at position 15: :还是先倒着匹配,即先看 (\̲d̲{3})* 再看\d{1,3}…符的特性

var str = "12345678";
var reg = /^\d{1,3}(\d{3})*$/g
console.log(str.match(reg)) //["12345678"]

11、重点例题

给一串数字添加千位分号

比如:

1234567 ——》 1,234,567

12 ——》 12

123456 ——》 123,456

实现:通过reg1的KaTeX parse error: Expected group after '^' at position 6: 符的特性和^̲符锁定,得到两部分,第一部分是前面剩余的数字,第二部分是后面长度为3的倍数部分。

当执行replace方法时,通过子表达式得到第二部分的内容,在用新的正则reg2添加逗号,从而实现

var str = "1234567890";
var reg1 = /^(\d{1,3})((\d{3})*)$/
var reg2 = /\d{3}/g
console.log(str.match(reg1))
var replaceStr = str.replace(reg1, function (match, p1, p2, p3) {
    return p1 + p2.replace(reg2, ",$&")
})
console.log(replaceStr);

12、gulp打包的时候,需要对html htm jsp文件中的js、css的版本号进行修改。我们要匹配文件中的css和js

以css为例:注意myselfCss是我自己实现的,匹配注意点:

(1)有些位置是可以有空格的,可以适当的进行匹配;但是href属性的地址中不允许有空格。

(2).*来匹配不确定的部分,比如rel=“stylesheet”,link标签中不仅有ref属性,重要的是必须有href属性。

(3)版本的标示不一定非要用字符t,可以是任意字符,但是为了规范,项目写的时候,就字符来标示版本变量吧。

这里必须吐槽一下:regCss是他们写项目的时候写的,用了很多没必要的(),是对正则匹配的优先级不了解造成的。

var str = '<link rel="stylesheet" href=" https://m/aaf_da-adas.css?t=12341234">';
var regCss = /<link.*href=("|')([^\"\']+.css((\?[a-z]|\_|\.)=([0-9a-zA-Z\.\_]+))*)("|')(.*)?\/?>/g;
var myselfCss = /<link.*href\s*=\s*(?:"|')\s*[^ ]*\.css\?[a-z]=[\w.]*\s*(?:"|')\s*>/g
console.log(str.match(myselfCss))
console.log(str.match(regCss))
 
["<link rel="stylesheet" href=" https://m/aaf_da-adas.css?t=12341234">"]
["<link rel="stylesheet" href=" https://m/aaf_da-adas.css?t=12341234">"]

13、相关的一些练习题

    //清除"数字"和"."以外的字符
    var str = "123@ da.2.99h";
    var reg = /[^\d.]/g
    console.log(str.replace(reg,""))
 
    //验证第一个字符是数字
    var str = "123@ da.2.99h";
    var reg = /^\d/;
    console.log(str.match(reg))
 
    //只保留第一个字符, 清除多余的
    var str = "safsfw1231";
    var reg = /(.).*/g;//匹配整个str
    console.log(str.replace(reg,"$1"))//用第一个字符替换整个str
 
    //只能输入两个小数
    var str = "0.12";
    var reg = /^\d+\.\d{2}$/g
    console.log(str.match(reg))
    </script>

最全的常用正则表达式大全

一、校验数字的表达式
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]+

三、特殊需求表达式
1. Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
2. 域名:[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(/.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+/.?
3. InternetURL:[a-zA-z]+://[^\s]*^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
4. 手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$
5. 电话号码("XXX-XXXXXXX""XXXX-XXXXXXXX""XXX-XXXXXXX""XXX-XXXXXXXX""XXXXXXX"和"XXXXXXXX)^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
6. 国内电话号码(0511-4405222021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
7. 身份证号(15位、18位数字)^\d{15}|\d{18}$
8. 短身份证号码(数字、字母x结尾)^([0-9]){7,18}(x|X)?$ 或 ^\d{8,18}|[0-9x]{8,18}|[0-9X]{8,18}?$
9. 帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线)^[a-zA-Z][a-zA-Z0-9_]{4,15}$
10. 密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)^[a-zA-Z]\w{5,17}$
11. 强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-10之间)^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
12. 日期格式:^\d{4}-\d{1,2}-\d{1,2}
13. 一年的12个月(0109112)^(0?[1-9]|1[0-2])$
14. 一个月的31天(0109131)^((0?[1-9])|((1|2)[0-9])|30|31)$
15. 钱的输入格式:
16. 1.有四种钱的表示形式我们可以接受:"10000.00""10,000.00", 和没有 "分""10000""10,000"^[1-9][0-9]*$
17. 2.这表示任意一个不以0开头的数字,但是,这也意味着一个字符"0"不通过,所以我们采用下面的形式:^(0|[1-9][0-9]*)$
18. 3.一个0或者一个不以0开头的数字.我们还可以允许开头有一个负号:^(0|-?[1-9][0-9]*)$
19. 4.这表示一个0或者一个可能为负的开头不为0的数字.让用户以0开头好了.把负号的也去掉,因为钱总不能是负的吧.下面我们要加的是说明可能的小数部分:^[0-9]+(.[0-9]+)?$
20. 5.必须说明的是,小数点后面至少应该有1位数,所以"10."是不通过的,但是 "10""10.2" 是通过的:^[0-9]+(.[0-9]{2})?$
21. 6.这样我们规定小数点后面必须有两位,如果你认为太苛刻了,可以这样:^[0-9]+(.[0-9]{1,2})?$
22. 7.这样就允许用户只写一位小数.下面我们该考虑数字中的逗号了,我们可以这样:^[0-9]{1,3}(,[0-9]{3})*(.[0-9]{1,2})?$
23. 8.13个数字,后面跟着任意个 逗号+3个数字,逗号成为可选,而不是必须:^([0-9]+|[0-9]{1,3}(,[0-9]{3})*)(.[0-9]{1,2})?$
24. 备注:这就是最终结果了,别忘了"+"可以用"*"替代如果你觉得空字符串也可以接受的话(奇怪,为什么?)最后,别忘了在用函数时去掉去掉那个反斜杠,一般的错误都在这里
25. xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
26. 中文字符的正则表达式:[\u4e00-\u9fa5]
27. 双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2ASCII字符计1))
28. 空白行的正则表达式:\n\s*\r (可以用来删除空白行)
29. HTML标记的正则表达式:<(\S*?)[^>]*>.*?</\1>|<.*? /> (网上流传的版本太糟糕,上面这个也仅仅能部分,对于复杂的嵌套标记依旧无能为力)
30. 首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
31. 腾讯QQ号:[1-9][0-9]{4,} (腾讯QQ号从10000开始)
32. 中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
33. IP地址:\d+\.\d+\.\d+\.\d+ (提取IP地址时有用)
34. IP地址:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值