正则表达式

正则表达式

0、概念

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

一、为什么使用正则表达式?

典型的搜索和替换操作要求您提供与预期的搜索结果匹配的确切文本。虽然这种技术对于对静态文本执行简单搜索和替换任务可能已经足够了,但它缺乏灵活性,若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。

通过使用正则表达式,可以:

  • 测试字符串内的模式。

例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。

  • 替换文本。

可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。

  • 基于模式匹配从字符串中提取子字符串。

可以查找文档内或输入域内特定的文本。

二、语法

2.1 普通字符

\w匹配字母、数字、下划线。等价于 [ A-Za-z0-9 ]
[ A-Z ]表示一个区间,匹配所有大写字母,[a-z] 表示所有小写字母。

2.2 特殊字符

*匹配前面的子表达式0次或多次
+匹配前面的子表达式1次或多次
?匹配前面的子表达式0次或1次,或指明一个非贪婪限定符
.匹配除换行符 \n 之外的任何单字符
^匹配输入字符串的开始位置
$匹配输入字符串的结尾位置
()标记一个子表达式的开始和结束位置
[标记一个中括号表达式的开始
{标记限定符表达式的开始
|指明两项之间的一个选择
\将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符

2.3 限定符

*匹配前面的子表达式0次或多次
+匹配前面的子表达式1次或多次
?匹配前面的子表达式0次或1次,或指明一个非贪婪限定符
{n}n 是一个非负整数。匹配确定的 n 次
{n,}至少匹配 n 次
{n,m}最少匹配 n 次且最多匹配 m 次

2.4 定位符

^匹配输入字符串的开始位置
$匹配输入字符串的结尾位置
\b匹配一个单词边界,即字与空格间的位置
\B非单词边界匹配

2.5 选择

用圆括号 () 将所有选择项括起来,相邻的选择项之间用 | 分隔

更多内容可以参考:正则表达式的先行断言(lookahead)和后行断言(lookbehind)

2.6 反向引用(不懂)

三、修饰符

标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。

标记不写在正则表达式里,标记位于表达式之外,格式如下:

/pattern/flags

i将匹配设置为不区分大小写
g查找所有的匹配项
m多行匹配
s特殊字符圆点 . 中包含换行符 \n

var str = “Google runoob taobao runoob”;

var patt1 = /runoob/g;

document.write(str.match(patt1));

四、运算符优先级

正则表达式从左到右进行计算,并遵循优先级顺序,这与算术表达式非常类似

img

一、常用正则表达式

(1)标点符号

/\p{P}/gu	//(包括中文标点),没空格和回车
/[\u0000-\u007F]/g	//不包括中文,有空格和回车

(2)数字

/\p{N}/gu
/[0-9]/g

(3)字母

/\p{L}/gu	//全部字母(大小写)
/\p{Lu}/gu	//大写
/\p{Ll}/gu	//小写

/[a-z]/g
/[A-Z]/g

(4)只允许输入葡文或者标点、特殊字符

下面展示一些 内联代码片

return (/^[\u00B5-\u00FF\u0000-\u007F|\p{P}|\p{N}|\p{S}|\p{Lu}|\p{Ll}|\p{N}]+$/gu).test(obj.value);

详细可看这里:

http://www.unicode.org/reports/tr18/

在这里插入图片描述

二、js正则相关函数

str.test(正则) 返回true、false

str.match(正则) 返回匹配的字符串,是数组形式

str.raplace(正则, ‘’) 去掉匹配的字符串

三、java正则相关函数

3.1 Pattern

Pattern是正则表达式的编译表示形式,构造方法私有,无法通过new创建对象

方法:

1. static Pattern compile(String regex)	// 将给定的正则表达式编译并赋予Pattern类

2. static Pattern compile(String regex, int flags)	// 同上,增加flag参数的指定,可选的flag参数包括:CASE INSENSITIVE(不区分大小写),MULTILINE(多行),DOTALL,UNICODE CASE, CANON EQ 

3. int flags()	// 返回当前Pattern的匹配flag参数

3.1 Matcher matcher() // 创建一个匹配器,将给定的输入与此模式进行匹配

4. String pattern() // 返回当前Pattern对象所编译的正则表达式

5. static String[] split(CharSequence input)	// 此方法用于分隔字符串,并返回一个String[]。

6. static boolean matcher(String regex,CharSequence input) // 此方法是一个静态方法,用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串

3.2 Matcher

匹配器类,通过解释 Pattern 对 character sequence 执行匹配操作的引擎。

方法:

1. boolean find() // 尝试查找与模式匹配的输入序列的下一个子序列。通常用在while中

1.1 int end() // 返回最后一个匹配字符之后的偏移量
2. String group() // group(0)得到的是匹配到的整个字符串,group(1)对应第一个括号的内容,group(2)对应第二个括号的内容,以此类推
例子:
@Test
public void groupTest(){
   String text = "abaaabccab1234ababcccab432dog";
   String regexp = "(a*b)([0-9]+)";
   Pattern pattern = Pattern.compile(regexp);

   Matcher matcher = pattern.matcher(text);
   while (matcher.find()){
       System.out.println("----------------");
       System.out.println(matcher.group());
       System.out.println(matcher.group(0)); //匹配到的整个字符串
       System.out.println(matcher.group(1)); //第一个括号
       System.out.println(matcher.group(2)); //第二个括号
   }
}

结果:
----------------
ab1234
ab1234
ab         //第一个括号
1234       //第二个括号
----------------
ab432
ab432
ab        //第一个括号
432       //第二个括号

Matcher 类同时提供了四个将匹配子串替换成指定字符串的方法:

1、 replaceAll()

2、 replaceFirst()

3、 appendReplacement()

4、 appendTail()

replaceAll() 与 replaceFirst() 的用法都比较简单,请看上面方法的解释。我们主要重点了解一下 appendReplacement() 和 appendTail() 方法。

appendReplacement(StringBuffer sb, String replacement) 将当前匹配子串替换为指定字符串,并且将替换后的子串以及其之前到上次匹配子串之后的字符串段添加到一个 StringBuffer 对象里,而 appendTail(StringBuffer sb) 方法则将最后一次匹配工作后剩余的字符串添加到一个 StringBuffer 对象里。

例如,有字符串 fatcatfatcatfat, 假设既有正则表达式模式为"cat",第一次匹配后调用 appendReplacement(sb,“dog”), 那么这时 StringBuffer sb 的内容为 fatdog,也就是 fatcat 中的 cat 被替换为 dog 并且与匹配子串前的内容加到 sb 里,而第二次匹配后调用 appendReplacement(sb,“dog”),那么 sb 的内容就变为 fatdogfatdog,如果最后再调用一次 appendTail(sb), 那么 sb 最终的内容将是 fatdogfatdogfat。

3.3 驼峰命名与下划线的相互转换

    /**
     * 驼峰命名转下划线
     * 方法一:匹配大写字母后面跟着一个小写字母,往前加“_”,再把大写转小写
     */
    public String camelToUnderLine1(String str) {

        // 例如:str = "allFiscalYearAllMonth"
        // 先要把首字母大写,方便匹配的时候往第一个分割处加“_”
        str = String.valueOf(str.charAt(0)).toUpperCase().concat(str.substring(1));
        // 得到 str = "AllFiscalYearAllMonth"

        String regex = "[A-Z](a-z\\d+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        // 这里匹配得到 ALL Fiscal Year All Month

        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            sb.append(matcher.group().toLowerCase());
            sb.append(matcher.end() == str.length() ? "" : "_");
        }
        // 最终得到 sb = "all_fiscal_year_all_month
        return sb.toString();
    }

    /**
     * 驼峰命名转下划线
     * 方法二:匹配大写字母,往前加“_”,再把大写转小写
     */
    public String camelToUnderLine2(String str) {

        // 例如:str = "allFiscalYearAllMonth"
        String regex = "[A-Z]";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        // 这里匹配得到:F Y A M

        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }



    /**
     * 下划线转驼峰命名
     * 方法一:用“_”作为分隔符,转成String[],然后再每个单词首字母大写,串起来再设置首字母小写
     */
    public String underLineToCamel(String str) {
        String[] tmp = XXXStrings.split(str, "_");
        StringBuilder sb = XXXStrings.sb();
        for (String s : tmp) {
            sb.append(XXXStrings.capitalize(s));
        }
        return XXXStrings.uncapitalize(sb.toString());
    }




    /**
     * 下划线转驼峰命名
     * 方法二:匹配字母或数字后面跟着“_”,截取匹配的这一段去掉_
     * @param str   源字符串
     * @param smallCamel    是否为小驼峰
     * @return  转换后的字符串
     */
    public String underLineToCamel2(String str, boolean smallCamel) {

        // 例如:str = "all_fiscal_year_all_month"
        String regex = "([A-Za-z\\d]+)(_)?";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        // 匹配得到: all_ fiscal_ year_ all_ month

        StringBuilder sb = new StringBuilder();
        while (matcher.find()) {
            String word = matcher.group();
            sb.append(smallCamel && matcher.start() == 0 ? Character.toLowerCase(word.charAt(0)) : Character.toUpperCase(word.charAt(0)));

            // String index = matcher.group(2);
            int index = word.lastIndexOf("_");
            if (index > 0) {
                sb.append(word.substring(1, index).toLowerCase());
            } else {
                sb.append(word.substring(1).toLowerCase());
            }
        }

        return sb.toString();
    }


    /***
     * 下划线转为驼峰
     * 方法三:
     **/
    public static String underlineToHump(String str) {
        str = str.toLowerCase();
        Pattern compile = Pattern.compile("_[a-z]");
        Matcher matcher = compile.matcher(str);
        StringBuffer sb = new StringBuffer();
        while(matcher.find()) {
            matcher.appendReplacement(sb,  matcher.group(0).toUpperCase().replace("_",""));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值