精华内容
下载资源
问答
  • java代码做正则校验

    2020-09-30 15:45:51
    在开发过程中,前端会做例如电话号码、邮箱等等之类的正则校验,为了保持数据的一致性,后端也要做类似的正则校验。 java代码示例 import java.util.regex.Pattern; public boolean isValid(String value) { //先...

    背景

    在开发过程中,前端会做例如电话号码、邮箱等等之类的正则校验,为了保持数据的一致性,后端也要做类似的正则校验。

    java代码示例

    import java.util.regex.Pattern;
    
    public boolean isValid(String value) {
    	//先做个非空校验
        if (StringUtil.isNullOrEmpty(value)) {
            return false;
        } else {
        	//中英文括号和-_.(常见名称允许输入的规则)
            String regex = "^[\\u4e00-\\u9fa5a-zA-Z\\d\\(\\)()\\-\\_\\.]+$";
            if (Pattern.matches(regex,value)) {
                return true;
            }
             return false;
        }
    }
    

    常用的正则

    //中英文(常见姓名允许输入的规则)
    String regex = "^[\\u4e00-\\u9fa5a-zA-Z]+$";
    //英文数字括号$¥和-_.(常见编码允许输入的规则)
    String regex = "^[a-zA-Z\\d\\(\\)()\\-\\_\\.\\s$¥]+$";
    

    补充:

    String自己就有正则匹配的方法,为.matchs(“正则表达式”)方法。其实这个方法底层也是调用的Pattern.matches(regex,value)方法,这个方法的返回值也是boolean类型的。

    展开全文
  • 分享大家供大家参考,具体如下: jQuery利用正则验证不能含有中文 var myReg = /^[a-zA-Z0-9_]{0,}$/; if (!myReg.test(input.val())) { $.validation.tip(false, input, "用户名不能含有中文或特殊字符"); ...
  • java后端做正则验证

    2019-12-23 14:06:13
    在项目中,前端要对特殊字段做正则验证,后端也要对特殊的字段做正则验证和非空判断,在做正则的时候遇到了很多坑,今天就和大家分享。主要有以下几种方式: 环境 springboot1.5.x jpa java8 1.结合注解来正则来校验 ...

    前言

    在项目中,前端要对特殊字段做正则验证,后端也要对特殊的字段做正则验证和非空判断,在做正则的时候遇到了很多坑,今天就和大家分享。主要有以下几种方式:

    环境

    springboot1.5.x
    jpa
    java8

    1.结合注解来正则来校验

    正则表达式

    package com.test.util;
    
    /**
     * 描述:正则表达式格式
     */
    public class RegexpProperties {
        public static final String MOBILE_PATTERN = "^$|0?(13|14|15|18|17)[0-9]{9}$";//手机号
        public static final String EMAIL_PATTERN = "^$|(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w+)+)$";//邮箱
        public static final String FAX_PATTERN = "^$|(\\d{3,4}-)?\\d{7,8}$";//传值
        public static final String CREDIT_CODE_PATTERN = "^$|[a-zA-Z0-9]{18}$";//社会信用代码
    }
    
    

    实体类

    package com.test.entity;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonInclude;
    import lombok.Getter;
    import lombok.Setter;
    import org.hibernate.annotations.DynamicInsert;
    import org.hibernate.annotations.DynamicUpdate;
    import org.hibernate.validator.constraints.Length;
    import org.hibernate.validator.constraints.NotBlank;
    import org.springframework.data.annotation.CreatedDate;
    import org.springframework.data.annotation.LastModifiedBy;
    import org.springframework.data.annotation.LastModifiedDate;
    import org.springframework.data.jpa.domain.support.AuditingEntityListener;
    
    import javax.persistence.*;
    import javax.validation.constraints.Max;
    import javax.validation.constraints.Min;
    import javax.validation.constraints.NotNull;
    import javax.validation.constraints.Pattern;
    import java.math.BigDecimal;
    import java.sql.Timestamp;
    import java.util.Date;
    
    @Table(name = "company")
    @Entity
    @Getter
    @Setter
    @DynamicInsert//新增时空字段不去插入values
    @DynamicUpdate//只跟新变化的字段,结合merge方法使用
    @JsonInclude(JsonInclude.Include.NON_NULL)
    @EntityListeners({AuditingEntityListener.class})
    @JsonIgnoreProperties({"createDate", "modifyDate"})
    public class Company implements BaseEntity{
        //BaseEntity 是实现序列化的,这个类我就不放进来了
    
        @Id
        @GeneratedValue
        private Integer id;
        @NotBlank(message = "企业名称不能为空")
        private String name;
        @NotBlank(message = "社会信用代码不能为空")
        @Pattern(regexp = RegexpProperties.CREDIT_CODE_PATTERN, message = "社会信用代码格式有误")
        private String creditCode;
        private String contactName;
        @Pattern(regexp = RegexpProperties.MOBILE_PATTERN, message = "电话格式有误")
        private String contactPhone;
        @Length(min = 0, max = 50, message = "企业法人长度不得超过50个字符")
        private String corporation;
        @Pattern(regexp = RegexpProperties.EMAIL_PATTERN, message = "邮箱格式有误")
        private String email;
        @Pattern(regexp = RegexpProperties.FAX_PATTERN, message = "传真格式有误")
        private String fax;
        private String address;
        @Min(value = 0, message = "占地面积不能小于0")
        private Double floorArea;
        private Integer attentionLevel;
        private Integer industryId;
        private String industryName;
        private Timestamp establishedDate;
        @Min(value = 0, message = "请输入正确的员工人数")
        private Integer staffNum;
        private Boolean isDeleted = false;
        
        @CreatedDate
        private Date createDate;
        @LastModifiedBy
        private Integer modifier;
        @LastModifiedDate
        private Date modifyDate;
    }
    
    

    该方法在新增或者修改的时使用, 在controller层中,
    在@RequestBody 前面加上@Validated 这种方能起作用.

    1.2正则验证手机号的另外一种方式

    package com.test.util;
    
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    
    import java.math.BigDecimal;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    import java.util.function.Function;
    import java.util.function.Supplier;
    import java.util.regex.Pattern;
    
    /**
     * 请求参数验证器
     */
    @Getter
    public class Validator {
        public static final int SUCCESS = 0;
        public static final int ARGUMENT_NULL = 101;
        public static final int ARGUMENT_ERROR = 102;
        private static final Pattern EMAIL_PATTERN = Pattern.compile("^(\\w)+(\\.\\w+)*@(\\w)+((\\.\\w+)+)$");
        private static final Pattern MOBILE_PATTERN = Pattern.compile("1\\d{10}");
        public static final Pattern FAX_PATTERN = Pattern.compile("^(\\d{3,4}-)?\\d{7,8}$");
        private static final Pattern TEL_PATTERN = Pattern.compile("^((0\\d{2,3})-)(\\d{7,8})(-(\\d{3,}))?$");
        private static final Pattern SPACE_PATTERN = Pattern.compile("\\s*|\t|\r|\n", Pattern.CASE_INSENSITIVE);
        private static final Pattern DATE_PATTERN =
                Pattern.compile("^\\d{4}[./-]\\d{1,2}[./-]\\d{1,2}[\\d\\.\\:\\+ZT ]+$", Pattern.CASE_INSENSITIVE);
        private static final Pattern EMOJI_PATTERN =
                Pattern.compile("[\\uD800-\\uDBFF\\uDC00-\\uDFFF\\u2600-\\u27ff]",
                        Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
        private static final Pattern IP_PATTERN =
                Pattern.compile("\\b((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])"
                        + "\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])"
                        + "\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])"
                        + "\\.((?!\\d\\d\\d)\\d+|1\\d\\d|2[0-4]\\d|25[0-5])\\b");
        private static final Pattern ID_CARD_NO_PATTERN =
                Pattern.compile("^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$");
        private final List<Valid> expressions = new ArrayList<>();
        private int code;
        private String message;
    
        public static Validator create() {
            return new Validator();
        }
    
        public static Validator create(String appId) {
            return Validator.create().appId(appId);
        }
    
        public static boolean isNullOrEmpty(String string) {
            return string == null || string.length() == 0;
        }
    
        public static boolean isPhone(String phone) {
            return !isNullOrEmpty(phone) && (TEL_PATTERN.matcher(phone).matches() || isMobile(phone));
        }
    
        public static boolean isMobile(String mobile) {
            return hasMobile(mobile) && mobile.length() == 11;
        }
    
        public static boolean hasMobile(String content) {
            return !isNullOrEmpty(content) && MOBILE_PATTERN.matcher(content).find();
        }
    
        public static boolean hasFax(String content) {
            return !isNullOrEmpty(content) && FAX_PATTERN.matcher(content).find();
        }
    
        public static boolean isFax(String fax) {
            return hasFax(fax) && fax.length() >= 7;
        }
    
        public static boolean isEmail(String email) {
            return hasEmail(email) && email.length() > 4;
        }
    
        public static boolean hasEmail(String content) {
            return !isNullOrEmpty(content) && EMAIL_PATTERN.matcher(content).find();
        }
    
        public static boolean isIp(String ip) {
            return !isNullOrEmpty(ip) && IP_PATTERN.matcher(ip).matches();
        }
    
        public static boolean hasEmoji(String text) {
            return !isNullOrEmpty(text) && EMOJI_PATTERN.matcher(text).matches();
        }
    
        /**
         * 是否身份证号
         */
        public static boolean isIdCardNO(String text) {
            return !isNullOrEmpty(text)
                    && text.length() >= 15
                    && ID_CARD_NO_PATTERN.matcher(text).matches();
        }
        
        public boolean valid() {
            for (Valid valid : expressions) {
                if (!valid.getExpression().get()) {
                    this.code = valid.getCode();
                    this.message = valid.getAlter();
                    return false;
                }
            }
            return true;
        }
    
        public <T> T convert(Function<Validator, T> function) {
            return function.apply(this);
        }
    
        public Validator valid(int code, String alter, Supplier<Boolean> expression) {
            Valid valid = new Valid(code, alter, expression);
            this.expressions.add(valid);
            return this;
        }
    
        public Validator validNull(String name, Supplier<Boolean> valid) {
            String alert = "缺少必要的请求参数:" + name;
            return valid(ARGUMENT_NULL, alert, valid);
        }
    
        public Validator validError(String name, Supplier<Boolean> valid) {
            String alert = "请求参数格式错误:" + name;
            return valid(ARGUMENT_ERROR, alert, valid);
        }
    
        public Validator appId(String appId) {
            return valid(ARGUMENT_NULL, "缺少参数 _appId", () -> !isNullOrEmpty(appId));
        }
    
        public Validator notNull(String name, Object value) {
            return validNull(name, () -> value != null);
        }
    
        public Validator notEmpty(String name, String value) {
            return validNull(name, () -> !isNullOrEmpty(value));
        }
    
        public Validator notEmpty(String name, Collection value) {
            return validNull(name, () -> value != null && value.size() > 0);
        }
    
        public Validator greaterThanZero(String name, Number value) {
            return greaterThan(name, value, 0);
        }
    
        public Validator greaterThan(String name, Number value, Number min) {
            String alert = String.format("%s 值必须大于 %s", name, min);
            return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() > min.doubleValue());
        }
    
        public Validator greaterThanOrEqual(String name, Number value, Number min) {
            String alert = String.format("%s 值必须大于等于 %s", name, min);
            return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() >= min.doubleValue());
        }
    
        public Validator lessThan(String name, Number value, Number max) {
            String alert = String.format("%s值必须小于 %s", name, max);
            return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() < max.doubleValue());
        }
    
        public Validator lessThanOrEqual(String name, Number value, Number max) {
            String alert = String.format("%s 值必须小于等于 %s", name, max);
            return valid(ARGUMENT_ERROR, alert, () -> value != null && value.doubleValue() <= max.doubleValue());
        }
    
        public Validator range(String name, Number value, Number min, Number max) {
            String alert = String.format("%s值必须在 [%s~%s] 之间", name, min, max);
            return valid(ARGUMENT_ERROR, alert, () -> value.doubleValue() >= min.doubleValue()
                    && value.doubleValue() <= max.doubleValue());
        }
    
        public Validator regexMatches(String name, String value, String pattern) {
            String alert = String.format("%s必须满足格式:%s", name, pattern);
            return valid(ARGUMENT_ERROR, alert, () -> Pattern.matches(pattern, value));
        }
    
        public Validator phone(String phone) {
            String alert = String.format("电话号码格式不正确,tel:[%s]", phone);
            return valid(ARGUMENT_ERROR, alert, () -> isPhone(phone));
        }
    
        public Validator mobile(String mobile) {
            String alert = String.format("手机号码格式不正确,mobile:[%s]", mobile);
            return valid(ARGUMENT_ERROR, alert, () -> isMobile(mobile));
        }
    
        public Validator email(String email) {
            String alert = String.format("邮箱格式不正确,email:[%s]", email);
            return valid(ARGUMENT_ERROR, alert, () -> isEmail(email));
        }
    
        public Validator idCardNo(String idCardNo) {
            String alert = String.format("身份证号格式不正确,number:[%s]", idCardNo);
            return valid(ARGUMENT_ERROR, alert, () -> isIdCardNO(idCardNo));
        }
    
        public Validator ip(String ip) {
            String alert = "ip地址格式不正确";
            return valid(ARGUMENT_ERROR, alert, () -> isIp(ip));
        }
    
        @Getter
        @Setter
        @NoArgsConstructor
        @AllArgsConstructor
        private class Valid {
            private int code;
            private String alter;
            private Supplier<Boolean> expression;
        }
    }
    
     /**
         * 验证手机号
         *
         * @param str 手机号
         * @return
         */
        public static boolean isMobile(String str) {
            boolean b = false;
            String s2 = "^$|0?(13|14|15|18|17)[0-9]{9}$";// 验证手机号
            if (Helpers.isNotNullAndEmpty(str)) {
                Pattern p = Pattern.compile(s2);
                Matcher m = p.matcher(str);
                b = m.matches();
            }
            return b;
        }
    
    /**
         * 验证不为空
         *
         *
         */
      Validator validator = Validator.create()
                        .notEmpty("用户名", user.getUserName())
                        .notEmpty("密码", user.getPassword())
                        .notEmpty("验证码", user.getCode())
                        .mobile(user.getMobile());
    
    
    
    展开全文
  • 前端正则校验

    2017-05-03 10:42:08
    持续更新中!!! 1. 有关时间框输入格式(00-23)格式的正则:^(0[0-9]|[1][0-9]|[2][0-3])$;亲测完美匹配!

    持续更新中!!!


    1. 有关时间框输入格式(00-23)格式的正则^(0[0-9]|[1][0-9]|[2][0-3])$亲测完美匹配

    展开全文
  • 正则表达式一般用于字符串匹配, 字符串查找和字符串替换. 别小看它的作用, 在工作学习中灵活运用正则表达式处理字符串能够大幅度提高效率, 编程的快乐来得就是这么简单。一下...

    640?wx_fmt=png

    正则表达式一般用于字符串匹配, 字符串查找和字符串替换. 别小看它的作用, 在工作学习中灵活运用正则表达式处理字符串能够大幅度提高效率, 编程的快乐来得就是这么简单。

    一下子给出一堆匹配的规则可能会让人恐惧, 下面将由浅入深讲解正则表达式的使用。

    从简单例子认识正则表达式匹配

    先上代码

    public class Demo1 {	
        public static void main(String[] args) {	
            //字符串abc匹配正则表达式"...", 其中"."表示一个字符	
            //"..."表示三个字符	
            System.out.println("abc".matches("..."));	
    
    	
            System.out.println("abcd".matches("..."));	
        }	
    }	
    //输出结果	
    true	
    false

    String类中有个matches(String regex)方法, 返回值为布尔类型, 用于告诉这个字符串是否匹配给定的正则表达式。

    在本例中我们给出的正则表达式为..., 其中每个.表示一个字符, 整个正则表达式的意思是三个字符, 显然当匹配abc的时候结果为true, 匹配abcd时结果为false

    Java中对正则表达式的支持(各种语言有相应的实现)

    java.util.regex包下有两个用于正则表达式的类, 一个是Matcher类, 另一个Pattern

    Java官方文档中给出对这两个类的典型用法, 代码如下:

    public class Demo2 {	
        public static void main(String[] args) {	
            //[a-z]表示a~z之间的任何一个字符, {3}表示3个字符, 意思是匹配一个长度为3, 并且每个字符属于a~z的字符串	
            Pattern p = Pattern.compile("[a-z]{3}");	
            Matcher m = p.matcher("abc");	
            System.out.println(m.matches());	
        }	
    }	
    //输出结果	
    true

    如果要深究正则表达式背后的原理, 会涉及编译原理中自动机等知识, 此处不展开描述. 为了达到通俗易懂, 这里用较为形象的语言描述。

    Pattern可以理解为一个模式, 字符串需要与某种模式进行匹配. 比如Demo2中, 我们定义的模式是一个长度为3的字符串, 其中每个字符必须是a~z中的一个

    我们看到创建Pattern对象时调用的是Pattern类中的compile方法, 也就是说对我们传入的正则表达式编译后得到一个模式对象. 而这个经过编译后模式对象, 会使得正则表达式使用效率会大大提高, 并且作为一个常量, 它可以安全地供多个线程并发使用。

    Matcher可以理解为模式匹配某个字符串后产生的结果. 字符串和某个模式匹配后可能会产生很多个结果, 这个会在后面的例子中讲解。

    最后当我们调用m.matches()时就会返回完整字符串与模式匹配的结果。

    上面的三行代码可以简化为一行代码

    System.out.println("abc".matches("[a-z]{3}"));

    但是如果一个正则表达式需要被重复匹配, 这种写法效率较低。

    初步认识 . + * ?

    在介绍之前首先要说明的是, 正则表达式的具体含义不用强背, 各个符号的含义在Java官方文档的Pattern类描述中或网上有详细的定义. 当然能熟用就更好了。

    public class Demo3 {	
        /**	
         * 为了省略每次写打印语句, 这里把输出语句封装起来	
         * @param o	
         */	
        private static void p(Object o){	
            System.out.println(o);	
        }	
    
    	
        /**	
         * .	Any character (may or may not match line terminators), 任意字符	
         * X?	X, once or not at all       零个或一个	
         * X*	X, zero or more times       零个或多个	
         * X+	X, one or more times        一个或多个	
         * X{n}	X, exactly n times          x出现n次	
         * X{n,}	X, at least n times     x出现至少n次	
         * X{n,m}	X, at least n but not more than m times 出现n~m次	
         * @param args	
         */	
        public static void main(String[] args) {	
            p("a".matches("."));	
            p("aa".matches("aa"));	
            p("aaaa".matches("a*"));	
            p("aaaa".matches("a+"));	
            p("".matches("a*"));	
            p("a".matches("a?"));	
    
    	
            // \d	A digit: [0-9], 表示数字, 但是在java中对"\"这个符号需要使用\进行转义, 所以出现\\d	
            p("2345".matches("\\d{2,5}"));	
            // \\.用于匹配"."	
            p("192.168.0.123".matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}"));	
            // [0-2]指必须是0~2中的一个数字	
            p("192".matches("[0-2][0-9][0-9]"));	
        }	
    }	
    //输出结果	
    //全为true

    范围

    []用于描述一个字符的范围, 下面是一些例子:

    public class Demo4 {	
        private static void p(Object o){	
            System.out.println(o);	
        }	
    
    	
        public static void main(String[] args) {	
            //[abc]指abc中的其中一个字母	
            p("a".matches("[abc]"));	
            //[^abc]指除了abc之外的字符	
            p("1".matches("[^abc]"));	
            //a~z或A~Z的字符, 以下三个均是或的写法	
            p("A".matches("[a-zA-Z]"));	
            p("A".matches("[a-z|A-Z]"));	
            p("A".matches("[a-z[A-Z]]"));	
            //[A-Z&amp;&amp;[REQ]]指A~Z中并且属于REQ其中之一的字符	
            p("R".matches("[A-Z&amp;&amp;[REQ]]"));	
        }	
    }	
    //输出结果	
    全部为true

    认识\s \w \d \

    下面介绍数字和字母的正则表达, 这是编程中使用最多的字符了.

    关于\

    这里重点介绍最不好理解的\. 在Java中的字符串中, 如果要用到特殊字符, 必须通过在前面加\进行转义。

    举个例子, 考虑这个字符串"老师大声说:"同学们,快交作业!"". 如果我们没有转义字符, 那么开头的双引号的结束应该在说:"这里, 但是我们的字符串中需要用到双引号, 所以需要用转义字符。

    使用转义字符后的字符串为"老师大声说:\"同学们,快交作业!\"", 这样我们的原意才能被正确识别。

    同理如果我们要在字符串中使用\, 也应该在前面加一个\, 所以在字符串中表示为"\\"

    那么如何在正则表达式中表示要匹配\呢, 答案为"\\\\"

    我们分开考虑: 由于正则式中表示\同样需要转义, 所以前面的\\表示正则表达式中的转义字符\, 后面的\\表示正则表达式中\本身, 合起来在正则表达式中表示\.

    如果感觉有点绕的话请看下面代码:

    public class Demo5 {	
        private static void p(Object o){	
            System.out.println(o);	
        }	
    
    	
        public static void main(String[] args) {	
            /**	
             * \d	A digit: [0-9]          数字	
             * \D	A non-digit: [^0-9]     非数字	
             * \s	A whitespace character: [ \t\n\x0B\f\r] 空格	
             * \S	A non-whitespace character: [^\s]       非空格	
             * \w	A word character: [a-zA-Z_0-9]          数字字母和下划线	
             * \W	A non-word character: [^\w]             非数字字母和下划线	
             */	
            // \\s{4}表示4个空白符	
            p(" \n\r\t".matches("\\s{4}"));	
            // \\S表示非空白符	
            p("a".matches("\\S"));	
            // \\w{3}表示数字字母和下划线	
            p("a_8".matches("\\w{3}"));	
            p("abc888&amp;^%".matches("[a-z]{1,3}\\d+[%^&amp;*]+"));	
            // 匹配 \	
            p("\\".matches("\\\\"));	
        }	
    }	
    //输出结果	
    全部为true

    边界处理

    ^在中括号内表示取反的意思[^], 如果不在中括号里则表示字符串的开头

    public class Demo6 {	
        private static void p(Object o){	
            System.out.println(o);	
        }	
    
    	
        public static void main(String[] args) {	
            /**	
             * ^	The beginning of a line 一个字符串的开始	
             * $	The end of a line       字符串的结束	
             * \b	A word boundary         一个单词的边界, 可以是空格, 换行符等	
             */	
            p("hello sir".matches("^h.*"));	
            p("hello sir".matches(".*r$"));	
            p("hello sir".matches("^h[a-z]{1,3}o\\b.*"));	
            p("hellosir".matches("^h[a-z]{1,3}o\\b.*"));	
        }	
    }

    练习:匹配空白行合email地址

    拿到一篇文章, 如何判断里面有多少个空白行? 用正则表达式能方便地进行匹配, 注意空白行中可能包括空格, 制表符等。

    p(" \n".matches("^[\\s&amp;&amp;[^\n]]*\\n$"));

    解释: ^[\\s&&[^\n]]*是空格符号但不是换行符, \\n$最后以换行符结束

    下面是匹配邮箱:

    p("liuyj24@126.com".matches("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+"));

    解释: [\\w[.-]]+以一个或多个数字字母下划线.-组成, @接着是个@符号, 然后同样是[\\w[.-]]+, 接着\\.匹配., 最后同样是[\\w]+

    Matcher类的matches(),find()lookingAt()

    matches()方法会将整个字符串与模板进行匹配.

    find()则是从当前位置开始进行匹配, 如果传入字符串后首先进行find(), 那么当前位置就是字符串的开头, 对当前位置的具体分析可以看下面的代码示例

    lookingAt()方法会从字符串的开头进行匹配.

    public class Demo8 {	
        private static void p(Object o){	
            System.out.println(o);	
        }	
    
    	
        public static void main(String[] args) {	
            Pattern pattern = Pattern.compile("\\d{3,5}");	
            String s = "123-34345-234-00";	
            Matcher m = pattern.matcher(s);	
    
    	
            //先演示matches(), 与整个字符串匹配.	
            p(m.matches());	
            //结果为false, 显然要匹配3~5个数字会在-处匹配失败	
    
    	
            //然后演示find(), 先使用reset()方法把当前位置设置为字符串的开头	
            m.reset();	
            p(m.find());//true 匹配123成功	
            p(m.find());//true 匹配34345成功	
            p(m.find());//true 匹配234成功	
            p(m.find());//false 匹配00失败	
    
    	
            //下面我们演示不在matches()使用reset(), 看看当前位置的变化	
            m.reset();//先重置	
            p(m.matches());//false 匹配整个字符串失败, 当前位置来到-	
            p(m.find());// true 匹配34345成功	
            p(m.find());// true 匹配234成功	
            p(m.find());// false 匹配00始边	
            p(m.find());// false 没有东西匹配, 失败	
    
    	
            //演示lookingAt(), 从头开始找	
            p(m.lookingAt());//true 找到123, 成功	
        }	
    }

    Matcher类中的start()end()

    如果一次匹配成功的话start()用于返回匹配开始的位置, end()用于返回匹配结束字符的后面一个位置

    public class Demo9 {	
        private static void p(Object o){	
            System.out.println(o);	
        }	
    
    	
        public static void main(String[] args) {	
            Pattern pattern = Pattern.compile("\\d{3,5}");	
            String s = "123-34345-234-00";	
            Matcher m = pattern.matcher(s);	
    
    	
            p(m.find());//true 匹配123成功	
            p("start: " + m.start() + " - end:" + m.end());	
            p(m.find());//true 匹配34345成功	
            p("start: " + m.start() + " - end:" + m.end());	
            p(m.find());//true 匹配234成功	
            p("start: " + m.start() + " - end:" + m.end());	
            p(m.find());//false 匹配00失败	
            try {	
                p("start: " + m.start() + " - end:" + m.end());	
            }catch (Exception e){	
                System.out.println("报错了...");	
            }	
            p(m.lookingAt());	
            p("start: " + m.start() + " - end:" + m.end());	
        }	
    }	
    //输出结果	
    true	
    start: 0 - end:3	
    true	
    start: 4 - end:9	
    true	
    start: 10 - end:13	
    false	
    报错了...	
    true	
    start: 0 - end:3

    替换字符串

    想要替换字符串首先要找到被替换的字符串, 这里要新介绍Matcher类中的一个方法group(), 它能返回匹配到的字符串.

    下面我们看一个例子, 把字符串中的java转换为大写.

    public class Demo10 {	
        private static void p(Object o){	
            System.out.println(o);	
        }	
    
    	
        public static void main(String[] args) {	
            Pattern p = Pattern.compile("java");	
            Matcher m = p.matcher("java Java JAVA JAva I love Java and you");	
            p(m.replaceAll("JAVA"));//replaceAll()方法会替换所有匹配到的字符串	
        }	
    }	
    //输出结果	
    JAVA Java JAVA JAva I love Java and you

    升级: 不区分大小写查找并替换字符串

    为了在匹配的时候不区分大小写, 我们要在创建模板模板时指定大小写不敏感

    public static void main(String[] args) {	
        Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);//指定为大小写不敏感的	
        Matcher m = p.matcher("java Java JAVA JAva I love Java and you");	
        p(m.replaceAll("JAVA"));	
    }	
    //输出结果	
    JAVA JAVA JAVA JAVA I love JAVA and you

    再升级: 不区分大小写, 替换查找到的指定字符串

    这里演示把查找到第奇数个字符串转换为大写, 第偶数个转换为小写

    这里会引入Matcher类中一个强大的方法appendReplacement(StringBuffer sb, String replacement), 它需要传入一个StringBuffer进行字符串拼接.

    public static void main(String[] args) {	
        Pattern p = Pattern.compile("java", Pattern.CASE_INSENSITIVE);	
        Matcher m = p.matcher("java Java JAVA JAva I love Java and you ?");	
        StringBuffer sb = new StringBuffer();	
        int index = 1;	
        while(m.find()){	
            //m.appendReplacement(sb, (index++ &amp; 1) == 0 ? "java" : "JAVA"); 较为简洁的写法	
            if((index &amp; 1) == 0){//偶数	
                m.appendReplacement(sb, "java");	
            }else{	
                m.appendReplacement(sb, "JAVA");	
            }	
            index++;	
        }	
        m.appendTail(sb);//把剩余的字符串加入	
        p(sb);	
    }	
    //输出结果	
    JAVA java JAVA java I love JAVA and you ?

    分组

    先从一个问题引入, 看下面这段代码

    public static void main(String[] args) {	
        Pattern p = Pattern.compile("\\d{3,5}[a-z]{2}");	
        String s = "123aa-5423zx-642oi-00";	
        Matcher m = p.matcher(s);	
        while(m.find()){	
            p(m.group());	
        }	
    }	
    //输出结果	
    123aa	
    5423zx	
    642oi

    其中正则表达式"\\d{3,5}[a-z]{2}"表示3~5个数字跟上两个字母, 然后打印出每个匹配到的字符串

    如果想要打印每个匹配串中的数字, 如何操作呢.

    首先你可能想到把匹配到的字符串再进行匹配, 但是这样太麻烦了, 分组机制可以帮助我们在正则表达式中进行分组.

    规定使用()进行分组, 这里我们把字母和数字各分为一组"(\\d{3,5})([a-z]{2})"

    然后在调用m.group(int group)方法时传入组号即可

    注意, 组号从0开始, 0组代表整个正则表达式, 从0之后, 就是在正则表达式中从左到右每一个左括号对应一个组. 在这个表达式中第1组是数字, 第2组是字母.

    public static void main(String[] args) {	
        Pattern p = Pattern.compile("(\\d{3,5})([a-z]{2})");//正则表达式为3~5个数字跟上两个字母	
        String s = "123aa-5423zx-642oi-00";	
        Matcher m = p.matcher(s);	
        while(m.find()){	
            p(m.group(1));	
        }	
    }	
    //输出结果	
    123	
    5423	
    642

    实战1: 抓取网页中的email地址(爬虫)

    假设我们手头上有一些优质的资源, 打算分享给网友, 于是便到贴吧上发出一个留邮箱发资源的帖子. 没想到网友热情高涨, 留下了近百个邮箱. 但逐个复制发送太累了, 我们考虑用程序实现.

    这里不展开讲发邮件部分, 重点应用已经学到的正则表达式从网页中截取所有的邮箱地址.

    首先获取一个帖子的html代码随便找了一个, 点击跳转[1], 在浏览器中点击右键保存html文件

    接下来看代码:

    public class Demo12 {	
        public static void main(String[] args) {	
            BufferedReader br = null;	
            try {	
                br = new BufferedReader(new FileReader("C:\\emailTest.html"));	
                String line = "";	
                while((line = br.readLine()) != null){//读取文件的每一行	
                    parse(line);//解析其中的email地址	
                }	
            } catch (FileNotFoundException e) {	
                e.printStackTrace();	
            } catch (IOException e) {	
                e.printStackTrace();	
            }finally {	
                if(br != null){	
                    try {	
                        br.close();	
                        br = null;	
                    } catch (IOException e) {	
                        e.printStackTrace();	
                    }	
                }	
            }	
        }	
    
    	
        private static void parse(String line){	
            Pattern p = Pattern.compile("[\\w[.-]]+@[\\w[.-]]+\\.[\\w]+");	
            Matcher m = p.matcher(line);	
            while(m.find()){	
                System.out.println(m.group());	
            }	
        }	
    }	
    //输出结果	
    2819531636@qq.com	
    2819531636@qq.com	
    2405059759@qq.com	
    2405059759@qq.com	
    1013376804@qq.com	
    ...

    实战2: 代码统计小程序

    最后的一个实战案例: 统计一个项目中一共有多少行代码, 多少行注释, 多少个空白行. 不妨对自己做过的项目进行统计, 发现不知不觉中也是个写过成千上万行代码的人了...

    我在github上挑选了一个项目, 是纯java写的小项目, 方便统计. 点击跳转[2]

    下面是具体的代码, 除了判断空行用了正则表达式外, 判断代码行和注释行用了String类的api

    public class Demo13 {	
        private static long codeLines = 0;	
        private static long commentLines = 0;	
        private static long whiteLines = 0;	
        private static String filePath = "C:\\TankOnline";	
    
    	
        public static void main(String[] args) {	
            process(filePath);	
            System.out.println("codeLines : " + codeLines);	
            System.out.println("commentLines : " + commentLines);	
            System.out.println("whiteLines : " + whiteLines);	
        }	
    
    	
        /**	
         * 递归查找文件	
         * @param pathStr	
         */	
        public static void process(String pathStr){	
            File file = new File(pathStr);	
            if(file.isDirectory()){//是文件夹则递归查找	
                File[] fileList = file.listFiles();	
                for(File f : fileList){	
                    String fPath = f.getAbsolutePath();	
                    process(fPath);	
                }	
            }else if(file.isFile()){//是文件则判断是否是.java文件	
                if(file.getName().matches(".*\\.java$")){	
                    parse(file);	
                }	
            }	
        }	
    
    	
        private static void parse(File file) {	
            BufferedReader br = null;	
            try {	
                br = new BufferedReader(new FileReader(file));	
                String line = "";	
                while((line = br.readLine()) != null){	
                    line = line.trim();//清空每行首尾的空格	
                    if(line.matches("^[\\s&amp;&amp;[^\\n]]*$")){//注意不是以\n结尾, 因为在br.readLine()会去掉\n	
                        whiteLines++;	
                    }else if(line.startsWith("/*") || line.startsWith("*") || line.endsWith("*/")){	
                        commentLines++;	
                    }else if(line.startsWith("//") || line.contains("//")){	
                        commentLines++;	
                    }else{	
                        if(line.startsWith("import") || line.startsWith("package")){//导包不算	
                            continue;	
                        }	
                        codeLines++;	
                    }	
                }	
            } catch (FileNotFoundException e) {	
                e.printStackTrace();	
            } catch (IOException e) {	
                e.printStackTrace();	
            } finally {	
                if(null != br){	
                    try {	
                        br.close();	
                        br = null;	
                    } catch (IOException e) {	
                        e.printStackTrace();	
                    }	
                }	
            }	
        }	
    }	
    //输出结果	
    codeLines : 1139	
    commentLines : 124	
    whiteLines : 172

    贪婪模式与非贪婪模式

    经过两个实战后, 相信大家已经掌握了正则表达式的基本使用了, 下面介绍贪婪模式与非贪婪模式.

    通过查看官方api我们发现Pattern类中有如下定义:

    Greedy quantifiers 贪婪模式	
    X?	X, once or not at all	
    X*	X, zero or more times	
    X+	X, one or more times	
    X{n}	X, exactly n times	
    X{n,}	X, at least n times	
    X{n,m}	X, at least n but not more than m times	
     	
    Reluctant quantifiers 非贪婪模式(勉强的, 不情愿的)	
    X??	X, once or not at all	
    X*?	X, zero or more times	
    X+?	X, one or more times	
    X{n}?	X, exactly n times	
    X{n,}?	X, at least n times	
    X{n,m}?	X, at least n but not more than m times	
     	
    Possessive quantifiers  独占模式	
    X?+	X, once or not at all	
    X*+	X, zero or more times	
    X++	X, one or more times	
    X{n}+	X, exactly n times	
    X{n,}+	X, at least n times	
    X{n,m}+	X, at least n but not more than m times

    这三种模式表达的意思是一样的, 在前面的讲解中我们全部使用的是贪婪模式. 那么其他两种模式的写法有什么区别呢? 通过下面的代码示例进行讲解.

    public static void main(String[] args) {	
        Pattern p = Pattern.compile(".{3,10}[0-9]");	
        String s = "aaaa5bbbb6";//10个字符	
        Matcher m = p.matcher(s);	
        if(m.find()){	
            System.out.println(m.start() + " - " + m.end());	
        }else {	
            System.out.println("not match!");	
        }	
    }	
    //输出结果	
    0 - 10

    正则表达式的意思是3~10个字符加一个数字. 在贪婪模式下匹配时, 系统会先吞掉10个字符, 这时检查最后一个是否时数字, 发现已经没有字符了, 于是吐出来一个字符, 再次匹配数字, 匹配成功, 得到0-10.

    下面是非贪婪模式演示(勉强的, 不情愿的)

    public static void main(String[] args) {	
        Pattern p = Pattern.compile(".{3,10}?[0-9]");//添加了一个?	
        String s = "aaaa5bbbb6";	
        Matcher m = p.matcher(s);	
        if(m.find()){	
            System.out.println(m.start() + " - " + m.end());	
        }else {	
            System.out.println("not match!");	
        }	
    }	
    //输出结果	
    0 - 5

    在非贪婪模式下, 首先只会吞掉3个(最少3个), 然后判断后面一个是否是数字, 结果不是, 在往后吞一个字符, 继续判断后面的是否数字, 结果是, 输出0-5

    最后演示独占模式, 通常只在追求效率的情况下这么做, 用得比较少

    public static void main(String[] args) {	
        Pattern p = Pattern.compile(".{3,10}+[0-9]");//多了个+	
        String s = "aaaa5bbbb6";	
        Matcher m = p.matcher(s);	
        if(m.find()){	
            System.out.println(m.start() + " - " + m.end());	
        }else {	
            System.out.println("not match!");	
        }	
    }	
    //输出结果	
    not match!

    独占模式会一下吞进10个字符, 然后判断后一个是否是数字, 不管是否匹配成功它都不会继续吞或者吐出一个字符.

    精彩回顾:

    面试的时候,如果你没掌握索引,绝对没戏!

    面试官:兄弟,说说 Spring Cloud 的核心架构原理吧

    如果有人问你 Dubbo 中注册中心工作原理,就把这篇文章给他

    < END >

    欢迎加入我们的知识星球,一起探讨技术、畅享人生。加入方式,长按下方二维码噢

    640?wx_fmt=png

    已在知识星球更新的优质内容如下:

    640?wx_fmt=png

    640?wx_fmt=png

    如果你喜欢这篇文章,欢迎在看、转发哦。

    让我们努力向前奔跑吧!

    展开全文
  • Java生成满足正则表达式的随机密码

    万次阅读 2019-06-08 11:36:45
    代码如下: public class ... 注意: 部分同学私信我说用了我的代码,但是用了自己的正则会出现栈溢出的情况,这是因为你的正则包含了一些没在CHARR中出现的特殊符号,你需要修改CHARR,如果把那些特殊符号添加进去。
  • 字符串去首尾空格在移动端java端都很方便,在前端貌似没有直接的系统方法去除 用如下正则可以去除首尾空格 val text = " \n a \n " + " s s s \n" + " " val regex = "^\\s*(([^\\s][\\s\\S]*[^\\s])|\\S)\\s...
  • 我把后端的验证规则直接前端同事用,反正在前端中出现编译出错。 二、对比了一下两个正则,发现是Java正则里面有很多转义的\,然后查询了一下Java与JavaScript正则表达式的转义的规则,发现两个是不一样的。...
  • Java-正则表达式

    万次阅读 多人点赞 2018-08-23 10:48:24
    正则表达式是处理字符串的强大的工具,它不是Java的特性,前端的JavaScript等也有。但是相比于其他老牌的高级语言,如C/C++,这是Java比他们独特的地方。 在正则表达式正式出场之前,我们先从熟悉的String类两个方法...
  • 正则表达式来规范的java登陆程序,基本的java程序来应用正则表达式。
  • 正则表达式是处理字符串的强大的工具,它不是Java的特性,前端的JavaScript等也有。但是相比于其他老牌的高级语言,如C/C++,这是Java比他们独特的地方。 一、正则表达式的概念: 理解可得:正则表达式其实就是一个...
  • 前端---正则表达式

    千次阅读 2018-01-04 13:38:12
    1.通过构造函数定义 var 变量名= new RegExp(/...(1)正则对象方法,检测测试字符串是否符合该规则,返回true和false,参数(测试字符串) (2)Boolean = 表达式.test("要验证的内容"); 4.预定义类 \d [0-9]
  • Web前端案例_正则表达式案例 这篇写关于一个正则表达式以及表单结合的案例。 1.案例说明 案例:利用正则表达式写一个表单验证 用户名:10-15位的数字或者字母 密码:10-15位的数字或字母 确认密码:判断两次输入...
  • Java正则匹配 以某个汉字开头和结束 Java代码示意: public static void main(String[] args) { String str = "正则匹配测试"; //以孕开头周结尾匹配 if (str.matches("(?:正).*") && str.matches(".*(?:...
  • Oracle Java Js 正则总结
  • web前端之JavaScript正则表达式 后面有代码: \d 表示数字 \d? ?表示0个或者一个 ...
  • 前端正则表达式

    2020-09-02 00:14:45
    正则表达式是用于匹配字符串中字符组合的模式,在Javasctipt中,正则表达式也是对象。 这正则表达式通常被用来检索,替换那些符合某个模式(规则)的文本,例如验证表单:用户名只能输入英文字母、数字或者下划线,...
  • 对一个数据利用正则验证,前端加了正则以后,后端还需要加上一层验证吗?</p>
  • Java中的正则

    2019-12-07 20:56:04
    今天带大家了解一下Java当中的正则,依旧采用我自己“”学习一个知识点的四部曲!“” 学习一个知识点的四部曲! 1.什么是它(正则)? 2.用它(正则)有什么好处?(这里得抛砖引玉,先讲没有它会出现什么问题,有了它解决...
  • 前端传参,调用接口 将两个值都传后端,做比较,符合条件,修改数据表中另一个字段值 init (id) { this.dataForm.id = id || 0 this.visible = true this.$nextTick(() => { this.$refs['dataForm']....
  • Java知识体系最强总结(2021版)

    万次阅读 多人点赞 2019-12-18 10:09:56
    本人从事Java开发已多年,平时有记录问题解决方案和总结知识点的习惯,整理了一些有关Java的知识体系,这不是最终版,会不定期的更新。也算是记录自己在从事编程工作的成长足迹,通过博客可以促进博主与阅读者的共同...
  • 1.1我这边需要对资讯内容进行打标更新,针对关键字需要转换Html的标签格式化进行替换掉展示高亮显示,然后进行前端展示,可是老代码是432个高亮词,100左右个标签,然后高亮显示,浏览器居然超时了,目前我们的架构...
  • 需求: 操作账号和密码框为... 长度为8-16位的“数字 + 字母 + 特殊符号”(注明:①数字、字母、特殊符 号的顺序无要求 ②特殊符号仅限 @ $ ^ ! ~ , .... 账号的校验正则: String valicateAccount="^[\\w@\\$...
  • Java正则表达式实现经纬度的合法性

    千次阅读 2020-01-03 21:55:30
    正则表达式: /^[\-\+]?(0?\d{1,2}\.\d{1,5}|1[0-7]?\d{1}\.\d{1,5}|180\.0{1,5})$/ 纬度: -90.0~+90.0(整数部分为0~90,必须输入1到5位小数) 正则表达式: /^[\-\+]?([0-8]?\d{1}\.\d{1,5}|90\.0{1,5}...
  • ![图片说明](https://img-ask.csdn.net/upload/201802/28/1519801443_455245.png) 请问正则表达式是什么
  • import java.util.regex.Pattern; public class TestSting2 { public static void main(String[] args) {
  • 很显然,这需要正则表达式过滤一下文件名字,直接上代码 String string = "今|: \\ \\ /// \" 天 \" _3:4/4 \\ _20*1?7content/2017-06/28/content_16240289.htm"; System.out.println(string); System.out....
  • 原文地址 :正则应用之——日期正则表达式 http://blog.csdn.net/akkzhjj/article/details/16867303 1概述 首先需要说明的一点,无论是Winform,还是Webform,都有很成熟的日历控件,无论从易用性还是可扩展性上...
  • 最近开发遇到一个新的东西,就是前端传过来一个字符串,需要将里面的数字提取出来,倒腾了一天,最后还是没有倒腾出来,最后还是借鉴大佬的方法。记录一下。 首先是前端传来的字符串“小明通过扫码向你付款100000....
  • Java 正则表达式数据校验

    万次阅读 2016-12-20 16:28:21
    前端转过来的数据进行校验,验证数据是否合法; 对用户名、密码、手机号、邮箱、身份证、中文进行校验.....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,362
精华内容 10,544
关键字:

java给前端正则

java 订阅