`

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  
学习了,不错啊.

相关推荐

    perl-5.26.1.tar.gz

    - 支持Unicode 9.0,增强了字符串和正则表达式的处理能力。 - `List::Util`模块新增了一些实用函数,如`minmax`,方便处理列表数据。 - 错误消息和诊断信息的改进,提高了调试的便利性。 Perl语法特点: - 采用C...

    Advanced Bash-Scripting Guide <>

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

    openssl-1.0.2d.tar.gz,pcre-8.37.tar.gz,zlib-1.2.8.tar.gz

    在Linux和其他使用PCRE的系统中,这个库广泛应用于文本处理、日志分析、数据提取、Web服务器(如Apache)的配置以及各种编程语言(如PHP、Python、Perl等)中,为开发者提供强大的字符串匹配和搜索功能。 3. Zlib:...

    Linux高级bash编程

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

    Python库 | utilmy-0.1.16343626-py3-none-any.whl

    3. **字符串处理**:字符串处理函数是许多编程任务的基础,`utilmy`可能提供了一些高级的字符串操作,比如格式化、模板化、正则表达式匹配等,方便进行文本处理和解析。 4. **日期时间**:日期和时间处理在很多应用...

    Python库 | stringutils-0.1.0-py2.py3-none-any.whl

    5. **模式匹配与查找**:通过正则表达式进行字符串的匹配、查找、替换等操作。 6. **编码与解码**:处理字符串的Unicode编码问题。 7. **字符串反转**:快速地将字符串倒序输出。 8. **去除重复字符**:返回没有重复...

    Bash-Beginners-Guide.pdf.zip_bash program_beginners

    Bash支持正则表达式,可以用于文件名扩展、字符串查找和替换等。熟悉正则表达式的基本语法和特殊字符,能极大提升在Bash中的数据处理能力。 **9. Shell编程技巧** 高级Bash编程技巧包括数组、位置参数、命令替换、...

    PyPI 官网下载 | twitter.common.string-0.3.11.tar.gz

    `twitter.common.string`是Twitter开源的一个模块,它包含了与字符串处理相关的各种工具和函数,旨在提高开发者在处理字符串时的效率和代码质量。这个库可能包含但不限于以下功能: 1. **字符串格式化**:提供了比...

    Python库 | stripenn-1.1.46-py3-none-any.whl

    2. **正则表达式操作**:`stripenn`可能扩展了Python的正则表达式操作,提供更方便的匹配、替换或分割字符串的函数。 3. **文本清洗**:在自然语言处理(NLP)中,清理文本数据是常见的步骤,该库可能包含用于去除...

    flex-2.5.4a-29.i386 flex-2.5.4a-29.i386.rpm

    词法分析器是编译器或解释器的第一步,它将源代码分解成一系列有意义的符号或标记,这些符号通常对应于编程语言的保留字、标识符、数字、字符串等。Flex通过读取用户定义的规则,自动生成词法分析器的C代码,然后...

    Python库 | cloudscraper-1.1.39-py2.py3-none-any.whl

    3. **自适应User-Agent**:它可以自动更改User-Agent字符串,避免被网站识别为爬虫。 4. **饼干管理**:库能处理服务器返回的cookies,保持会话状态。 5. **IP代理支持**:支持使用代理IP,帮助在IP被封锁时继续爬取...

    Python库 | utilityhelper-0.1.8-py2.py3-none-any.whl

    通常,这样的库会提供如字符串处理、日期时间操作、JSON解析、正则表达式匹配、异常处理等功能。开发者可以通过import utilityhelper的方式引入,并调用其中的函数来使用。 Python库的安装,对于utilityhelper-...

    Advanced.Bash-Scripting.Guide.Cn.txt

    在Bash脚本中,可以使用多种方法对字符串进行处理,包括拼接、分割、替换等。 ##### 3.1 字符串拼接 可以通过简单地将字符串放在一起实现拼接: ```bash str1="hello" str2="world" echo "$str1 $str2" ``` #####...

    bash过滤字符串的命令介绍

    在Linux系统中,Bash shell提供了一系列强大的命令来处理字符串,这些命令包括grep、sed、cut等。本文将详细介绍这些命令的功能、参数及其使用方法。 首先,让我们来看看grep命令。grep全称为Global Regular ...

    Bash-Scripting-源码.rar

    - Bash支持正则表达式匹配,如`[[ string =~ pattern ]]`进行模式匹配。 7. **文件与目录操作** - **文件测试**: `-f`, `-d`, `-e`, `-r`, `-w`, `-x`等用于测试文件属性。 - **文件处理**: `touch`, `cp`, `mv`...

    Python库 | onigurumacffi-0.0.16-cp38-cp38-win32.whl

    在本例中,onigurumacffi库特别关注正则表达式,这是一个强大的文本模式匹配工具,广泛应用于字符串搜索、替换、解析等各种场景。 正则表达式在Python中通常通过内置的`re`模块来使用,但onigurumacffi提供了一种...

    PyPI 官网下载 | regex-2018.07.11-cp33-none-win32.whl

    标签"Python库"表明这是一款为Python编程语言设计的软件包,它扩展了Python的标准库功能,使得开发者在处理文本和字符串时拥有更多的可能性。在Python中,库通常通过`import`语句导入并使用。 在Python中,`.whl`...

    PyPI 官网下载 | clldutils-3.2.0-py2.py3-none-any.whl

    1. **数据验证**:提供了一套用于检查数据完整性的函数,例如验证字符串是否符合特定的正则表达式模式。 2. **地理编码**:可以将地理位置的文本描述转换为经纬度坐标,对地理信息进行处理。 3. **时间处理**:支持...

    PyPI 官网下载 | regex-2015.11.07-cp35-none-win32.whl

    在Python编程中,正则表达式(Regular Expression,简称regex)是一种强大的文本处理工具,它能用于搜索、替换、提取等操作,尤其在处理字符串时,其灵活性和高效性是其他方法难以比拟的。而`regex`库是Python社区...

    Python库 | regexapp-0.2.0-py3-none-any.whl

    正则表达式(Regular Expression,简称regex)是用于匹配字符串的强大工具,广泛应用于文本搜索、替换和提取信息。Python标准库中的`re`模块已经提供了对正则表达式的支持,但有些情况下,开发者可能会需要更高级、...

Global site tag (gtag.js) - Google Analytics