正则表达式是什么
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。一般我用正则做字符校验。
常用元字符
代码 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线 |
\s | 匹配任意的空白符 |
\d | 匹配数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
常用限定符
代码/语法 | 说明 |
---|---|
* | 重复零次或更多次 |
+ | 重复一次或更多次 |
? | 重复零次或一次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
常用反义词
代码/语法 | 说明 |
---|---|
\W | 匹配任意不是字母,数字,下划线,汉字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非数字的字符 |
\B | 匹配不是单词开头或结束的位置 |
[^x] | 匹配除了x以外的任意字符 |
[^aeiou] | 匹配除了aeiou这几个字母以外的任意字符 |
常用模式修正符
代码/语法 | 说明 |
---|---|
i | 表示在进行匹配的时候不区分大小写 |
m | 多行识别.即将字符串视为多行,不管是那行都能匹配 |
s | 将字符串视为单行,转义回车换行符作为普通字符 |
g | 表示全局匹配 |
x | 将模式中的空白忽略 |
A | 强制从目标字符串开头匹配 |
D | 强制尾部无任何内容.若使用$限制结尾字符,则不允许结尾有换行 |
U | 禁止贪婪匹配,只匹配最近的一个字符串(不重复匹配) |
e | 配合PHP函数preg_replace()使用,可以把匹配来的字符串当作正则表达式执行 |
参考:http://tools.jb51.net/regex/create_reg
写一个字符串的校验:
例如:[tid1,N2,H,L]=[tid2,N2,H,L]+[tid3,N2,H,L]+...+[tid..,N2,H,L];H=1..5;L=1...5
tid指表ID,是36位生成的id里面会有数字英文字母和横杠
N2是区域ID,N为不变的字符,2为动态的数字
H和L分布指的是行范围和列范围,是用分号后面的数字范围替换前面的H和L
例子翻译过来就是:
tid1的N2区域的1-5行的值等于tid2的N2区域的1-5行的值+tid3的N2区域的1-5行的值+...+tid若干的N2区域的1-5行的值,列也同理。
正则:
/\[(\w|\-){36},([NW]\d,)?(\(?(((H|\d+)(\-|\+)(H|\d+))|(H|\d+))\)?),((\d+(\-|\+)\d+)|(L|\d+))\](=|<>|>|>=|<|<=)\[(\w|\-){36},([NW]\d,)?(\(?(((H|\d+)(\-|\+)(H|\d+))|(H|\d+))\)?),(L|\d+)\](([\+|\-|\*|\/])\[(\w|\-){36},([NW]\d,)?(\(?(((H|\d+)(\-|\+)(H|\d+))|(H|\d+))\)?),(L|\d+)\])*(;H=\d+\.{3}\d+)?(;L=\d+\.{3}\d+)?/g
这正则的意思就是
以/开始/g结束,用()括起来代表这是一个字符块,“|”是或的意思
\[(\w|\-){36} \是字符的转义“\[”就是匹配字符[,“\w|\-” 是匹配任意英文字母和数字和下划线或者匹配“-”这个字符,{36}表示这样重复的匹配字符36次。
([NW]\d,)?这是匹配N后面跟一个任意数字后面跟一个逗号的字,?代表这个字符块存在一次或者不存在。
(\(?(((H|\d+)(\-|\+)(H|\d+))|(H|\d+))\)?) “\(” 和“\)”是转义为()字符,(H|\d+)(\-|\+)(H|\d+))|(H|\d+)表示这个位置的值可以是H,或者任意数字且数字存在一次或多次,再可以加或者减字符存在。后面的同理
(=|<>|>|>=|<|<=) 这是匹配=,<>,>,>=,<,<=运算符
(([\+|\-|\*|\/])\[(\w|\-){36},([NW]\d,)?(\(?(((H|\d+)(\-|\+)(H|\d+))|(H|\d+))\)?),(L|\d+)\])*
这是先匹配加减乘除的运算符在匹配上面翻译过的字符然后括起来后面加一个*,就是代表+[tid,N2,H,L]这么个字符块存在零次或多次。实现为
[tid1,N2,H,L]=[tid2,N2,H,L]这样可以匹配,[tid1,N2,H,L]=[tid2,N2,H,L]+如果个[tid2,N2,H,L]字符块都可以匹配。
最后(;H=\d+\.{3}\d+)?(;L=\d+\.{3}\d+)? 是字符块里以“;”字符开头匹配H=存在一次或多次的任意字符,中间\.{3}代办“.”这个字符重复3次,字符块存在一次或零次。后面的L也同理
;H=1..5;L=1...5这种形式的字符匹配。
由于第一次写正则表达式,我写完以后忘记加“/g”,然后在就一直报缺少“/”的错。当时我就把那么长的正则在每个字母的看,看哪缺少了"/",看了几次都没有找到,之后对比其他写完且正确的正则发现我缺少了“/g”这个字符,查了一下才知道需要以“/”开头以“/g”结束。
总的来说,写正则就是写一个字符的规则,把一个长字符串单独里的每个字符作为一个原子来看,在归类这些原子,找出类型相似的原子,通过正则的语法写出来就行。一般用到的正则都可以根据上面的表格里展示的正则的常用规则来写就行了。
例子:
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HelloWorld {
public static void main(String []args) {
boolean aa = checkMatches("3322e211");
System.out.println("Hello World "+aa);
}
//求只能输入整数或小数的正则表达式
private static boolean checkMatches(String value) {
String pattern = "^[0-9]+([.]{1}[0-9]+){0,1}$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(value);
if (m.find()) {
return true;
}
return false;
}
}