0
点赞
收藏
分享

微信扫一扫

Python模块、迭代器、正则表达式

前两天遇到一个需求,大概是这样:

有"放射性废物分类", "放射性物质", "放射性", "放射", "性" 这样一组词语,要在 这样一段话中匹配 ‘’关于发布《放射性废物分类》的公告,放射性物质是有害物质,放射元素会影响人的医生”,要求如果长的包含短的只匹配长的,比如放射性包含放射和性,在放射性物质中只匹配放射性,匹配到的要前后加<em></em>

实现这样的功能就想到了正则表达式,下面先了解简单的正则语法

1.正则表达式介绍

正则表达式(Regular Expression),通常简称为“正则”或“Regex”,是⼀种⽤于描述字符串模式 的表达式。它是由字符和运算符组成的⽂本模式,⽤于匹配、查找或替换⽂本中的字符序列。

主要功能 :

匹配⽂本模式; 查找和替换 ;数据提取 ;表单验证 ;⽂本处理⼯具

2.正则表达式语法

正则表达式(正则)的语法由⼀系列字符和操作符组成,⽤于定义字符串的模式。以下是⼀些常⻅ 的正则表达式语法元素:

2.1字⾯字符

普通字符: ⼤多数字符表示它们⾃身。例如,字⺟和数字⼤多直接匹配⾃身。

2.2元字符

  • .(点):
匹配除换⾏符之外的任意字符。 a.b // 匹配 "aab"、"axb"、"a@b" 等 
  • ^: 匹配字符串的开头。
^abc // 匹配以 "abc" 开头的字符串 
  • $: 匹配字符串的结尾。
xyz$ // 匹配以 "xyz" 结尾的字符串 
  • \d \D 匹配⼀个数字或⾮数字
  • \n 匹配换⾏符
  • \s \S 匹配空⽩字符 或 ⾮空⽩字符
  • \w \W 匹配任何单词 或 ⾮单词 [A-Za-z0-9_]

2.3 字符类

[...]: 匹配⽅括号内的任何字符

 [aeiou] // 匹配任何⼀个元⾳字⺟ 

^ 表示取反,匹配不在⽅括号内的任何字符。

[^0-9] // 匹配任何⾮数字字符  

2.4量词

  • *: 匹配零次或多次前⾯的元素。
a* // 匹配 "a"、"aa"、"aaa" 等 
  • +: 匹配⼀次或多次前⾯的元素。
 b+ // 匹配 "b"、"bb"、"bbb" 等 
  • ?: 匹配零次或⼀次前⾯的元素。
c? // 匹配 "c" 或空字符串 
  • {n}: 匹配恰好 n 次前⾯的元素。
d{3} // 匹配 "ddd" 
  • {n,}: 匹配⾄少 n 次前⾯的元素。
 e{2,} // 匹配 "ee"、"eee"、"eeee" 等
  • {n,m}: 匹配⾄少 n 次且不超过 m 次前⾯的元素。
f{2,4} // 匹配 "ff"、"fff"、"ffff" 

这些元素只是正则表达式语法的⼀部分,正则表达式还有许多⾼级特性和选项,具体取决于⽀持正 则表达式的⼯具或语⾔。学习正则表达式通常需要不断练习和实践,逐渐掌握其强⼤的⽂本匹配和 处理能⼒

3.正则表达式⾼级特性

3.1 转义字符

\: 转义字符,⽤于匹配元字符本身。

\. // 匹配句点字符 "." 
\? // 匹配? 
\+ // 匹配+ 
\* // 匹配*  

3.2分组和捕获

(...): 创建⼀个分组,可以对其应⽤量词。

 (abc)+ // 匹配 "abc"、"abcabc" 等 group(1) 可以获取 

(?:...): ⾮捕获分组,不捕获匹配的内容。

 (?:ab)+ // 匹配 "ab"、"abab" 等,group(1) 获取不到  

3.3 零宽断⾔

(?=...): 正向肯定预查,匹配在某些内容之前的位置。

a(?=b) // 匹配 "a",但仅当其后⾯跟着"b" 

(?!...): 正向否定预查,匹配不在某些内容之前的位置。

x(?!y) // 匹配 "x",但仅当其后⾯不跟着 "y" 

(?<=...): 反向肯定预查,匹配在某些内容之后的位置。

 (?<=a)b // 匹配 "b",但仅当其前⾯是 "a" 

(?<!...):反向否定预查,匹配不在某些内容之后的位置

(?<!x)y  //匹配y,但前边不是x

5.使⽤正则提取指定的内容

提取数字:

public void testNum() {
        String text = "这⾥有⼀些数字:12, 34, 56, 78";
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
}

提取XML属性

   public void testXMLAttr() {
        String text = "<a  text=\"value\">Example</a>";
        Pattern pattern = Pattern.compile("a\\s*=\\s*\"[^\"]+\"");
        Matcher matcher = pattern.matcher(text);
        while (matcher.find()) {
            System.out.println(matcher.group());
        }
    }

结果:

text="value"

6.实现问题功能

public class KeywordHighlighter {
    public static void main(String[] args) {
        // 给定的一段话
        String text = "关于发布《放射性废物分类》的公告,放射性物质是有害物质,放射元素会影响人的医生";

        // 关键词列表,按长度降序排列
        String[] keywords = {"放射性废物分类", "放射性物质", "放射性", "放射", "性"};

        // 调用方法进行匹配和高亮
        String highlightedText = replaceKeywords(text, keywords);

        // 打印结果
        System.out.println(highlightedText);
    }

    public static String replaceKeywords(String text, String[] keywords) {
        // 按长度降序排序关键词
        Arrays.sort(keywords, (a, b) -> b.length() - a.length());

        // 构建正则表达式
        StringBuilder patternBuilder = new StringBuilder();
        for (String keyword : keywords) {
            if (patternBuilder.length() > 0) {
                patternBuilder.append("|");
            }
            patternBuilder.append(Pattern.quote(keyword));
        }

        // 编译正则表达式
        Pattern pattern = Pattern.compile(patternBuilder.toString());
        Matcher matcher = pattern.matcher(text);

        // 替换匹配到的关键词
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "<em>" + matcher.group() + "</em>");
        }
        matcher.appendTail(sb);

        return sb.toString();
    }
}


代码解释

举报

相关推荐

0 条评论