正则表达式详解——在安卓开发中的应用指南和常见用法

631 阅读6分钟

前言

概括

在安卓开发中,正则表达式(Regular Expression)是一种强大的工具,用于处理字符串的匹配、替换和提取操作。它在处理输入验证、数据格式化和文本处理等方面非常有用。

细分

分为三点:

1.正则表达式定义了字符串的模式;

2.正则表达式可以用来搜索、编辑或处理文本;

3.正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别;

正则表达式中用到的特殊字符

当涉及到正则表达式的特殊字符时,下面是一些示例和详细解释:

特殊字符示例

  1. .(句点):

    • 正则表达式:a.b
    • 匹配的字符串:axb, a1b, a_b
    • 解释:.匹配任意单个字符,所以这个正则表达式可以匹配 "a" 和 "b" 之间有一个字符的字符串。
  2. *

    • 正则表达式:ab*c
    • 匹配的字符串:ac, abc, abbc, abbbc, ...
    • 解释:* 表示前面的元素可以出现零次或多次,所以这个正则表达式可以匹配以 "a" 开头,以 "c" 结尾,中间有任意数量的 "b" 的字符串。
  3. +

    • 正则表达式:ab+c
    • 匹配的字符串:abc, abbc, abbbc, ...
    • 解释:+ 表示前面的元素至少出现一次或更多次,所以这个正则表达式可以匹配以 "a" 开头,中间至少有一个或多个 "b",以 "c" 结尾的字符串。
  4. ?

    • 正则表达式:colou?r
    • 匹配的字符串:color, colour
    • 解释:? 表示前面的元素可以出现零次或一次,所以这个正则表达式可以匹配 "color" 或 "colour" 这两种拼写方式。
  5. |

    • 正则表达式:abandon|boring
    • 匹配的字符串:abandon, boring
    • 解释:| 表示选择,用于在两个或多个模式之间进行选择匹配。这个正则表达式可以匹配 "apple" 或 "banana"。
  6. []

    • 正则表达式:[aeiou]
    • 匹配的字符串:a, e, i, o, u
    • 解释:[] 是字符类,表示匹配其中的任意一个字符。这个正则表达式可以匹配元音字母。
  7. ()

    • 正则表达式:(ab)+
    • 匹配的字符串:ab, abab, ababab, ...
    • 解释:() 是捕获组,可以将其中的表达式作为一个整体进行限定。这个正则表达式可以匹配连续出现的 "ab"。
  8. {}:限定符。用于指定匹配元素出现的次数范围。

    • 正则表达式:a{2,4}
    • 匹配的字符串:aa, aaa, aaaa
    • 解释:{2,4} 表示前面的元素 "a" 必须出现 2 到 4 次。这个正则表达式可以匹配由 2 到 4 个 "a" 组成的字符串。
  9. \:转义字符。用于转义特殊字符,使其失去特殊含义。

    • 正则表达式:\d+
    • 匹配的字符串:123, 45678, 9999
    • 解释:\d 表示匹配一个数字字符。通过 \ 转义,可以表示一个数字字符。这个正则表达式可以匹配一连串的数字。
  10. ^:表示行的开头。在多行模式下,还可表示每行的开头。

    • 正则表达式:^Start
    • 匹配的字符串:Start of something, Start again
    • 解释:^ 表示匹配行的开头。这个正则表达式可以匹配以 "Start" 开头的字符串。
  11. $:表示行的结尾。在多行模式下,还可表示每行的结尾。

    • 正则表达式:end$
    • 匹配的字符串:The end, The journey has no end
    • 解释:$ 表示匹配行的结尾。这个正则表达式可以匹配以 "end" 结尾的字符串。
  12. \b:单词边界。表示匹配一个单词的边界,确保匹配的内容是一个完整的单词。

    • 正则表达式:\bword\b
    • 匹配的字符串:This word is boring, Can Can Word!
    • 解释:\b 表示单词的边界。这个正则表达式可以匹配完整的单词 "word"。
  13. \d:匹配一个数字字符。等效于 [0-9]

    • 正则表达式:\d{3}
    • 匹配的字符串:123, 456
    • 解释:\d 表示匹配一个数字字符。这个正则表达式可以匹配连续的三个数字字符。
  14. \w:匹配一个字母、数字或下划线字符。等效于 [A-Za-z0-9_]

    • 正则表达式:\w+
    • 匹配的字符串:hello_world, apple, o泡果奶
    • 解释:\w 表示匹配一个字母、数字或下划线字符
  15. \s:匹配任意空白字符,包括空格、制表符、换行符等。等效于 [\t\n\r\f\v]

    • 正则表达式:hello\sworld
    • 匹配的字符串:hello world, hello\tworld, hello\nworld
    • 解释:\s 表示匹配一个空白字符。这个正则表达式可以匹配 "hello" 后紧跟一个空白字符,然后是 "world"。
  16. \t:匹配制表符(Tab符号)。

    • 正则表达式:Hello\tworld
    • 匹配的字符串:Hello world
    • 解释:\t 表示匹配一个制表符。这个正则表达式可以匹配 "Hello" 后紧跟一个制表符,然后是 "world"。

以上是一些常见的特殊字符的示例和解释。希望这些示例能够帮助到觉友们,有不足的地方欢迎大家查漏补缺。

部分特殊字符概念延伸

注解:7: () 是捕获组,可以将其中的表达式作为一个整体进行限定,这个符号之关键于此句中!顺便延伸: 在正则表达式中,圆括号 () 用于创建一个捕获组(capturing group)。捕获组可以将匹配的部分提取出来或在正则表达式中进行分组和重复使用。

具体来说,圆括号的作用如下:

  1. 分组:圆括号可以将正则表达式中的一部分内容组合在一起,形成一个子表达式。这可以用于对子表达式应用限定符(如 *+? 等)或进行逻辑操作(如使用 | 进行选择)。

  2. 捕获:圆括号内的内容被视为一个捕获组,可以将匹配到的内容提取出来以供后续处理。通过捕获组,你可以在匹配后的操作中引用、替换或进一步处理捕获到的内容。

提供一个最近工作中使用的正则表达式 ([0-9]+[.]?[0-9]*)[ \t]*((克|kg|千克|gram|grams|gramów)) 中,有两个捕获组:

  1. ([0-9]+[.]?[0-9]*):这是第一个捕获组,用于匹配数字(包括整数和浮点数)。这个捕获组中的内容可以在匹配后提取出来,以获取匹配到的数字。

  2. ((克|kg|千克|gram|grams|gramów)):这是第二个捕获组,用于匹配重量单位(包括 "克"、"kg"、"千克"、"gram"、"grams"、"gramów")。这个捕获组中的内容可以在匹配后提取出来,以获取匹配到的重量单位。

通过捕获组,你可以从匹配到的文本中提取出数字和重量单位,进行进一步的处理或使用。

提取捕获组代码示例

java代码提取(适用于AndroidStudio环境,也可使用AS自动转换为kotlin代码)

String text = "I like apple";
Pattern pattern = Pattern.compile("(apple|banana|orange)");
Matcher matcher = pattern.matcher(text);

if (matcher.find()) {
    String result = matcher.group(1);
    System.out.println(result);  // 输出:apple
}

python代码提取(使用于Pycharm环境)

import re

text = "I like apple"
pattern = re.compile(r"(apple|banana|orange)")
match = pattern.search(text)

if match:
    result = match.group(1)
    print(result)  # 输出:apple

解释下上述代码使用到的几个类的含义(这几个类含义取自菜鸟教程)

  • Pattern 类:

    pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

  • Matcher 类:

    Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

  • PatternSyntaxException:

    PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

还有注意一下1.2.3.4条目的特殊字符解释,这些字符要区别开零次/一次/多次,这个勿要弄混!~

特殊字符中的转义字符

上述十五个特殊字符中有部分有反斜杠\ ,在java中,反斜杠起到转义的作用,例如,\b就是转义字符b转义特殊字符b,但是在java字符串中为了表示 \b 字符本身,需要使用双反斜杠 \b 进行转义。

正则表达式代码举例

邮箱验证

String regex = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
String email = "example@example.com";
//如果 `email` 字符串与 `regex` 正则表达式匹配,`matches` 方法将返回 `true`,否则返回 `false`。通过检查返回的布尔值,可以确定给定的邮箱地址是否符合预期的模式。
boolean isValid = email.matches(regex); 

手机号码验证

String regex = "^[1-9]\d{10}$";
String phoneNumber = "12345678901";
boolean isValid = phoneNumber.matches(regex);

URL验证

String regex = "^(http|https)://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?$";
String url = "https://www.baidu.com";
boolean isValid = url.matches(regex);

身份证ID验证

String regex = "^\\d{17}(\\d|x|X)$";
String idNumber = "12345678901234567X";
boolean isValid = idNumber.matches(regex);

整数验证

String regex = "^-?\\d+$";
String number = "-123";
boolean isValid = number.matches(regex);

IP地址验证

String regex = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
String ipAddress = "192.168.0.1";
boolean isValid = ipAddress.matches(regex);

工作中最近用到的正则表达式

一个较复杂的正则表达式

"([0-9]+[.]?[0-9]*)[ \\t]*((g|克|kg|千克|gram|grams|gramów)\\b)"

这个正则表达式用于匹配一个字符串,其中包含一个数值表示重量(可能是小数),后面跟着一个重量单位(以克为单位)。下面是该正则表达式的解释:

  1. "("")":圆括号用于分组,将正则表达式的不同部分组合在一起。
  2. [0-9]+:匹配一个或多个数字(0到9之间的任意数字)。
  3. [.]?:匹配零个或一个句点字符(小数点)。句点前面的 [] 表示将句点字符视为普通字符,不是正则表达式中的特殊字符。
  4. [0-9]*:匹配零个或多个数字。
  5. [ \\t]*:匹配零个或多个空格或制表符。[ \\t] 中的 \\t 表示制表符字符。
  6. "("")":再次使用圆括号进行分组。
  7. (g|克|kg|千克|gram|grams|gramów):匹配括号内的任意一个字符串(单位选择)。可以是 "g"、"克"、"kg"、"千克"、"gram"、"grams" 或 "gramów"。
  8. \\b:边界匹配器,用于确保单位单词的边界。确保匹配的单位单词不是其他单词的一部分。

综上所述,该正则表达式将匹配形如 "123.45g"、"0.5 kg"、"100 grams" 等表示重量的字符串,其中数值可以是整数或小数,单位可以是 "g"、"克"、"kg"、"千克"、"gram"、"grams" 或 "gramów"。

工作中常用到的过滤敏感词汇功能

过滤敏感词汇工具类代码

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SensitiveWordFilter {

    private Pattern pattern;

    public SensitiveWordFilter(String[] sensitiveWords) {
        // 构建正则表达式模式
        StringBuilder patternBuilder = new StringBuilder();
        for (String word : sensitiveWords) {
            if (patternBuilder.length() > 0) {
                patternBuilder.append("|");
            }
            patternBuilder.append(Pattern.quote(word));
        }
        String regex = patternBuilder.toString();

        // 创建正则表达式模式对象
        pattern = Pattern.compile(regex);
    }

    public String filterText(String text) {
        // 进行文本匹配和替换
        Matcher matcher = pattern.matcher(text);
        return matcher.replaceAll("***");
    }
}

调用工具类

public class XXXActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xxx);

        String text = "这是一段包含敏感词汇的文本,比如色情、赌博和暴力。请文明发言。";

        // 敏感词汇列表
        String[] sensitiveWords = {"孙笑川", "色情", "赌博", "暴力"};

        // 创建敏感词过滤器实例
        SensitiveWordFilter filter = new SensitiveWordFilter(sensitiveWords);

        // 过滤文本
        String filteredText = filter.filterText(text);

        TextView textView = findViewById(R.id.text_view);
        textView.setText("原文本:" + text + "\n\n" + "过滤后的文本:" + filteredText);
    }
}

总结

通过本文的学习,掘友们将能够掌握正则表达式在Android开发中的基本应用。了解正则表达式的基础知识和常见特殊字符,并通过实际示例演示其在文本验证、匹配、替换和提取中的实际应用。掌握正则表达式将帮助开发人员更高效地处理文本操作,并提升应用的功能和用户体验。