`

Bash字符串处理(与Java对照) - 21.字符串正则匹配

阅读更多

Bash字符串处理(与Java对照) - 21.字符串正则匹配

In Java

正则表达式查询

String.matches方法

boolean     matches(String regex)

          通知此字符串是否匹配给定的正则表达式。

String str = "123456";
String re = "\\d+";
if (str.matches(re)) {
    // do something
}
 

Pattern类和Matcher类

String str = "abc efg ABC";
String re = "a|f"; //表示a或f
Pattern p = Pattern.compile(re);
Matcher m = p.matcher(str);
boolean rs = m.find();
 

如果str中有re,那么rs为true,否则为flase。如果想在查找时忽略大小写,则可以写成Pattern p = Pattern.compile(re, Pattern.CASE_INSENSITIVE);

 

正则表达式提取

String re = ".+\\(.+)$";
String str = "c:\\dir1\\dir2\\name.txt";
Pattern p = Pattern.compile(re);
Matcher m = p.matcher(str);
boolean rs = m.find();
for (int i = 1; i <= m.groupCount(); i++) {
    System.out.println(m.group(i));
}

 
以上的执行结果为name.txt,提取的字符串储存在m.group(i)中,其中i最大值为m.groupCount();

 

正则表达式分割

 

String re = "::";
Pattern p = Pattern.compile(re);
String[] r = p.split("xd::abc::cde");

 
执行后,r就是{"xd","abc","cde"},其实分割时还有跟简单的方法:

String str="xd::abc::cde";
String[] r = str.split("::");
 

正则表达式替换(删除)

String re = "a+"; //表示一个或多个a
Pattern p = Pattern.compile(re);
Matcher m = p.matcher("aaabbced a ccdeaa");
String s = m.replaceAll("A");

 

结果为"Abbced A ccdeA"
  
如果写成空串,既可达到删除的功能,比如:

String re = "a+"; //表示一个或多个a
Pattern p = Pattern.compile(re);
Matcher m = p.matcher("aaabbced a ccdeaa");
String s = m.replaceAll("");
 

结果为"bbced ccde"

 

String.replaceAll 和 String.replaceFirst 是可执行正则表达式替换(删除)的简易做法。但String.replace不是按正则表达式来进行的。

JavaDoc class String 写道
String replace(char oldChar, char newChar)
    Returns a new string resulting from replacing all occurrences of oldChar in this string with newChar.
String replace(CharSequence target, CharSequence replacement)
    Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence.
String replaceAll(String regex, String replacement)
    Replaces each substring of this string that matches the given regular expression with the given replacement.
String replaceFirst(String regex, String replacement)
    Replaces the first substring of this string that matches the given regular expression with the given replacement.
 

Java中常用的正则表达式元字符

. 代表任意字符
? 表示前面的字符出现0次或1次
+ 表示前面的字符出现1次或多次
* 表示前面的字符出现0次或多次
{n} 表示前面的字符出现正好n次
{n,} 表示前面的字符出现n次或以上
{n,m} 表示前面的字符出现n次到m次
\d 等于 [0-9] 数字
\D 等于 [^0-9] 非数字
\s 等于 [ \t\n\x0B\f ] 空白字元
\S 等于 [^ \t\n\x0B\f ] 非空白字元
\w 等于 [a-zA-Z_0-9] 数字或是英文字
\W 等于 [^a-zA-Z_0-9] 非数字与英文字
^ 表示每行的开头

$ 表示每行的结尾

 

In Bash

关于Linux下正则表达式的说明,详见 http://codingstandards.iteye.com/blog/1195592

 

Bash对正则表达式的支持

Bash v3 内置对正则表达式匹配的支持,操作符为 =~。(Bash Version 3)

[[ "$STR" =~ "$REGEX" ]]

man bash 写道
[[ expression ]]
       An  additional  binary  operator,  =~,  is available, with the same precedence as == and !=.  When it is
       used, the string to the right of the operator is considered an extended regular expression  and  matched
       accordingly (as in regex(3)).  The return value is 0 if the string matches the pattern, and 1 otherwise.
       If the regular expression is syntactically incorrect, the conditional expression’s return  value  is  2.
       If  the shell option nocasematch is enabled, the match is performed without regard to the case of alpha-
       betic characters.  Substrings matched by parenthesized subexpressions within the regular expression  are
       saved  in  the  array variable BASH_REMATCH.  The element of BASH_REMATCH with index 0 is the portion of
       the string matching the entire regular expression.  The element of BASH_REMATCH with index n is the por-
       tion of the string matching the nth parenthesized subexpression.

在Bash中二元操作符 =~ 进行扩展的正则表达式匹配。如果匹配,返回值为0,否则1,如果正则表达式错误,返回2。如果shell选项nocasematch没有开启,那么匹配时 区分大小写。在正则表达式中小括号包围的子表达式的匹配结果保存在BASH_REMATCH中,它是个数组,${BASH_REMATCH[0]}是匹配 的整个字符串,${BASH_REMATCH[1]}是匹配的第一个子表达式的字符串,其他以此类推。

 

以下脚本来自 http://www.linuxjournal.com/content/bash-regular-expressions 很好的展示了Bash3.0中内置的正则表达式匹配功能。

#!/bin/bash

if [[ $# -lt 2 ]]; then
    echo "Usage: $0 PATTERN STRINGS..."
    exit 1
fi
regex=$1
shift
echo "regex: $regex"
echo

while [[ $1 ]]
do
    if [[ $1 =~ $regex ]]; then
        echo "$1 matches"
        i=1
        n=${#BASH_REMATCH[*]}
        while [[ $i -lt $n ]]
        do
            echo "  capture[$i]: ${BASH_REMATCH[$i]}"
            let i++
        done
    else
        echo "$1 does not match"
    fi
    shift
done
 

[root@jfht ~]# ./bashre.sh 'aa(b{2,3}[xyz])cc' aabbxcc aabbcc
regex: aa(b{2,3}[xyz])cc

aabbxcc matches
  capture[1]: bbx
aabbcc does not match
[root@jfht ~]#

 

在grep/egrep命令中进行正则表达式匹配

使用Basic RE

格式1:echo "$STR" | grep -q "$REGEX"

格式2:grep -q "$REGEX" <<<"$STR"

使用Extended RE

格式3:echo "$STR" | egrep -q "$REGEX"

格式4:egrep -q "$REGEX" <<<"$STR"

注意:grep/egrep加上-q参数是为了减少输出,根据退出码判断是否匹配,退出码为0时表示匹配。

man grep 写道
Egrep is the same as grep -E.

       -E, --extended-regexp
              Interpret PATTERN as an extended regular expression (see below).

       -e PATTERN, --regexp=PATTERN
              Use PATTERN as the pattern; useful to protect patterns beginning with -.

       -q, --quiet, --silent
              Quiet;  do  not  write  anything  to standard output.  Exit immediately with zero status if any match is
              found, even if an error was detected.  Also see the -s or --no-messages option.
 

 

匹配手机号码,模式为:1[3458][0-9]{9}  或  1[3458][0-9]\{9\}

[root@jfht ~]# echo "13012345678" | egrep '1[3458][0-9]{9}'
13012345678
[root@jfht ~]# echo "13012345678" | grep '1[3458][0-9]{9}'
[root@jfht ~]# echo "13012345678" | grep '1[3458][0-9]\{9\}'
13012345678
[root@jfht ~]#

 

STR="13024184301"
REGEX="1[3458][0-9]{9}"
if echo "$STR" | egrep -q "$REGEX"; then
    echo "matched"
else
    echo "not matched"
fi

 

 

[root@jfht ~]# STR="13024184301"
[root@jfht ~]# REGEX="1[3458][0-9]{9}"
[root@jfht ~]# if echo "$STR" | egrep -q "$REGEX"; then
    echo "matched"
> else
>     echo "not matched"
> fi
matched
[root@jfht ~]#

 

使用expr match进行正则表达式匹配

expr match "$STR" "$REGEX"

expr "$STR" : "$REGEX"

打印与正则表达式匹配的长度。

 

man expr 写道
STRING : REGEXP
    anchored pattern match of REGEXP in STRING
match STRING REGEXP
    same as STRING : REGEXP

 

[root@jfht ~]# STR=Hello
[root@jfht ~]# REGEX=He
[root@jfht ~]# expr "$STR" : "$REGEX"
2

[root@jfht ~]# REGEX=".*[aeiou]"
[root@jfht ~]# expr "$STR" : "$REGEX"
5

注意:贪婪匹配!

[root@jfht ~]# REGEX=ll
[root@jfht ~]# expr "$STR" : "$REGEX"
0

 

另外,expr match 也可以实现根据正则表达式取子串。

expr match "$STR" ".*\($SUB\).*"

expr "$STR" : ".*\($SUB\).*"

注意与上面不同的是,结果是子串,而不是匹配的长度。

 

[root@jfht ~]# STR="某某是2009年进公司的"

想从此字符串中提取出数字来,下面是尝试的过程。
[root@jfht ~]# SUB="[0-9]+"
[root@jfht ~]# expr "$STR" : ".*\($SUB\).*"

[root@jfht ~]# SUB="[0-9]\+"               
[root@jfht ~]# expr "$STR" : ".*\($SUB\).*"
9
[root@jfht ~]# SUB="[0-9]*"                
[root@jfht ~]# expr "$STR" : ".*\($SUB\).*"

[root@jfht ~]# SUB="[0-9]\*"               
[root@jfht ~]# expr "$STR" : ".*\($SUB\).*"

 

上面的写法都无法做到提取完整的年份,因为在正则匹配的时候是贪婪匹配,前面.*已经把能匹配的全部吃掉了。
[root@jfht ~]# expr "$STR" : "[^0-9]*\([0-9]\+\).*"
2009

 

网上问题:形如"someletters_12345_moreleters.ext"的文件名,以一些字母开头、跟上下划线、跟上5个数字、再跟上下划线、以一些字母及扩展名结尾。现在需要将数字提取出来,保存到一个变量中。

 

[root@jfht ~]# echo someletters_12345_moreleters.ext | cut -d'_' -f 2
12345

[root@jfht ~]# expr match 'someletters_12345_moreleters.ext' '.\+_\(.\+\)_.*'
12345

 

[root@jfht ~]# FILE=someletters_12345_moreleters.ext
[root@jfht ~]# NUM=$(expr match "$FILE" '.\+_\(.\+\)_.*')
[root@jfht ~]# echo $NUM
12345

 

 

本文链接:http://codingstandards.iteye.com/blog/1208526   (转载请注明出处)

返回目录:Java程序员的Bash实用指南系列之字符串处理(目录) 

上节内容:Bash字符串处理(与Java对照) - 20.查找子串的位置

下节内容:Bash字符串处理(与Java对照) - 22.判断字符串是否数字串

 

 

5
2
分享到:
评论
1 楼 superlittlefish 2011-10-24  
学习了,不错啊.

相关推荐

    Advanced Bash-Scripting Guide <>

    使用模式匹配来分析比较特殊的字符串 9-20. 对字符串的前缀或后缀使用匹配模式 9-21. 使用declare 来指定变量的类型 9-22. 间接引用 9-23. 传递一个间接引用给awk 9-24. 产生随机数 9-25. 从一副扑克牌中取出一张...

    Linux高级bash编程

    使用模式匹配来分析比较特殊的字符串 9-20. 对字符串的前缀或后缀使用匹配模式 9-21. 使用declare来指定变量的类型 9-22. 间接引用 9-23. 传递一个间接引用给awk 9-24. 产生随机数 9-25. 从一副扑克牌中取出一张...

    SubEthaEdit-5.1.3.zip 可以写文章,代码,笔记

    强大的荧光笔基于状态,正则表达式和纯文本字符串。模式可以相互引用,因此HTML模式具有全功能的CSS和javascript部分。 语法样式 这些模式引用样式的语义层次结构,可以对其进行自定义以匹配您的首选项。 自动...

    anymatch:将字符串与可配置的字符串,glob,正则表达式和_或函数进行匹配

    Javascript模块,用于将字符串与正则表达式,glob,字符串或以字符串作为参数并返回true或falsy值的函数进行匹配。 匹配器也可以是所有这些或全部的数组。 对于允许非常灵活的用户定义的配置来定义诸如文件路径之类...

    高级Bash脚本编程指南.pdf

    操作字符串 9.3. 参数替换 9.4. 指定变量的类型: 使用declare或者typeset 9.5. 变量的间接引用 9.6. $RANDOM: 产生随机整数 9.7. 双圆括号结构 10. 循环与分支 10.1. 循环 10.2. 嵌套循环 10.3. 循环...

    高级bash脚本编程指南(中英文合集)

    9.2. 操作字符串 9.3. 参数替换 9.4. 指定类型的变量:declare 或者typeset 9.5. 变量的间接引用 9.6. $RANDOM: 产生随机整数 9.7. 双圆括号结构 10. 循环和分支 10.1. 循环 10.2. 嵌套循环 10.3. 循环控制 ...

    ubuntu部落(适合初学者,可以作为初学者的手册)

    安装JAVA 环境..................................... 18 安装多媒体播放驱动............................. 20 Linux 基础.............................................................. 23 Shell ................

    宋劲彬的嵌入式C语言一站式编程

    2.7. 以字符串为单位的I/O函数 2.8. 以记录为单位的I/O函数 2.9. 格式化I/O函数 2.10. C标准库的I/O缓冲区 2.11. 本节综合练习 3. 数值字符串转换函数 4. 分配内存的函数 26. 链表、二叉树和哈希表 1. 链表 1.1. ...

    学习shell必备(CN).chm

    9.2. 操作字符串 9.3. 参数替换 9.4. 指定变量的类型: 使用declare或者typeset 9.5. 变量的间接引用 9.6. $RANDOM: 产生随机整数 9.7. 双圆括号结构 10. 循环与分支 10.1. 循环 10.2. 嵌套循环 10.3. 循环控制 10.4....

    xah-find:纯emacs lisp中的findreplace命令

    •可靠地查找/替换包含很多Unicode字符的字符串。 查看和•可靠地查找/替换包含很多转义斜杠或反斜杠的字符串。 例如,查找/替换源代码中正则表达式的字符串。 主页: : 在我的 patreon 中投入 5 美元。

    入门学习Linux常用必会60个命令实例详解doc/txt

    这是因为Linux和许多版本的Unix一样,提供了虚拟控制台的访问方式,允许用户在同一时间从控制台(系统的控制台是与系统直接相连的监视器和键盘)进行多次登录。每个虚拟控制台可以看作是一个独立的工作站,工作台...

    专家教您如何在C语言中巧用正则表达式

    由于它可以极大地简化处理字符串时的复杂度,因此现在已经在许多Linux实用工具中得到了应用。千万不要以为正则表达式只是Perl、Python、Bash等脚本语言的专利,作为C语言程序员,用户同样可以在自己的程序中运用正则...

    linux培训初中高级和资深课程视频.zip

    目录网盘文件永久链接 01_01_面授班开场 01_02_面授班开场 01_03_操作系统基础 ...06_03_bash脚本编程之五 字符串测试及for循环 07_01_vim编辑器详解 07_02_bash脚本编程之六 使用脚本选项及组合条件测试.......

    python-regex-notes:有关生物学研究生脚本课程的Python正则表达式的一些说明

    在Python中使用正则表达式(regex)与在Bash中使用正则表达式非常相似。 主要区别在于,我们将创建和使用正则表达式压缩对象(设计用于处理正则表达式模式的类的实例)。 除此之外,我们描述要查找的模式的语法非常...

    《Linux操作系统实训教程》周奇上机实验报告

    本书提供11个实训项目,内容包括Linux操作系统的搭建与测试、文件和目录操作、用户信息、Linux文件系统、bash的基本使用、标准输入输出和管道、字符串处理、使用正则表达式进行字符处理、进程控制、编辑工具的使用和...

    RED HAT LINUX 6大全

    本书全面系统地介绍了Red Hat Linux 6。全书共分为五个部分,包括35章和四个附录。第一部分为Red Hat Linux的介绍和安装;第二部分为服务配置;第三部分为系统管理;第四部分为Linux编程;...14.9.21 security=(G...

    regextester:一个CLI工具,用于使用各种正则表达式样式(bre,ere,pcre等)测试正则表达式(regex)

    RegexTester模板 一个用于使用各种正则表达式语言测试正则表达式(regex)的CLI工具。 目录 安装/设置 ... regext从stdin读取测试字符串,因此您可以| 来自echo或cat管子。 范例1: echo " abcd

    pgrep命令 用于检索当前正在运行的进程

    pgrep命令就是检索正在运行的进程,显示匹配准则是进程的PID,可跟正则表达式来匹配进程或命令行。 选择进程拥有者时,默认匹配规则是逻辑与的关系。 语法格式:pgrep [参数] [模式] 常用参数: -d 设置一个字符...

    图像如何分割matlab代码-octSegmentation:出版物“使用全局形状正则化的3-DOCT图像中概率性视网膜内层分割”的参考代码(

    其中xxx是指向该目录的字符串 调用函数compileMex来编译所有C函数 例子 该软件包提供了两种模型(数据文件/模型文件)用于循环扫描和3-D体积,并使用我们标记的基本事实进行了训练。 不幸的是,我们不允许发布任何...

Global site tag (gtag.js) - Google Analytics