golang正则表达式的使用及举例

news2024/10/28 7:25:35

正则表达式很强大,在一些场合如抓包,爬虫等方面很有用。在 Go语言中,正则表达式通过标准库 regexp 提供支持。使用正则表达式可以进行字符串匹配、替换和分割等操作。

以下是正则表达式的基本使用方法及示例:

1. 导入 regexp 包

在你的 Go 代码中,首先需要导入 regexp 包:

import (
    "fmt"
    "regexp"
)

2. 编译正则表达式

使用 regexp.Compile 或 regexp.MustCompile 来编译正则表达式。MustCompile 在编译出错时会导致程序崩溃,因此对于已知的正则表达式可直接使用它。

re, err := regexp.Compile("a([a-z]+)e")
if err != nil {
    fmt.Println("Error compiling regex:", err)
}

或使用:

re := regexp.MustCompile("a([a-z]+)e")
3. 使用正则表达式

编译后的正则表达式可以用于多种功能:

3.1. 匹配字符串

使用 MatchString 函数判断字符串是否符合正则表达式。

matched := re.MatchString("apple")
fmt.Println("Matched:", matched) // 输出: Matched: true
3.2. 查找匹配

使用 FindString 获取匹配的子串。

result := re.FindString("I have an apple here.")
fmt.Println("Found:", result) // 输出: Found: apple
3.3. 查找所有匹配

使用 FindAllString 获取所有匹配的子串。

results := re.FindAllString("I have an apple and an axe here.", -1)
fmt.Println("Found all:", results) // 输出: Found all: [apple axe]
3.4. 替换

使用 ReplaceAllString 替换匹配的子串。

replaced := re.ReplaceAllString("I have an apple and an axe here.", "fruit")
fmt.Println("Replaced:", replaced) // 输出: Replaced: I have an fruit and an fruit here.
3.5. 分割字符串

使用 Split 函数按照正则表达式分割字符串。

splitStrings := re.Split("I have an apple and an axe here.", -1)
fmt.Println("Split:", splitStrings) // 输出: Split: [I have an  and an  here.]

完整示例

下面是一个完整的示例,演示了上述功能:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    // 编译正则表达式
    re := regexp.MustCompile("a([a-z]+)e")

    // 匹配字符串
    matched := re.MatchString("apple")
    fmt.Println("Matched:", matched) // 输出: Matched: true

    // 找到匹配的字符串
    result := re.FindString("I have an apple here.")
    fmt.Println("Found:", result) // 输出: Found: apple

    // 找到所有匹配的字符串
    results := re.FindAllString("I have an apple and an axe here.", -1)
    fmt.Println("Found all:", results) // 输出: Found all: [apple axe]

    // 替换匹配的子串
    replaced := re.ReplaceAllString("I have an apple and an axe here.", "fruit")
    fmt.Println("Replaced:", replaced) // 输出: Replaced: I have an fruit and an fruit here.

    // 按照正则表达式分割字符串
    splitStrings := re.Split("I have an apple and an axe here.", -1)
    fmt.Println("Split:", splitStrings) // 输出: Split: [I have an  and an  here.]
}

要让正则表达式也能匹配到 HelloWorld 这样的字符串,你需要构建一个更灵活的正则表达式,允许字符之间有可选的连字符、空白字符或 · 字符,同时也能匹配连续的字符。

示例代码

package main

import (
    "fmt"
    "regexp"
    "strings"
)

func fuzzyMatch(pattern, text string) bool {
    // 将 pattern 拆分为多个部分
    parts := strings.Split(pattern, "")
    // 构建正则表达式模式
    var regexParts []string
    for _, part := range parts {
        regexParts = append(regexParts, regexp.QuoteMeta(part))
    }
    regexPattern := strings.Join(regexParts, `[-\s·]?`)
    // 构建最终的正则表达式
    finalPattern := fmt.Sprintf("^.*%s.*$", regexPattern)
    re := regexp.MustCompile(finalPattern)
    // 进行匹配
    return re.MatchString(text)
}

func main() {
    pattern := "HelloWorld"
    texts := []string{
        "Hello-World",
        "Hello World",
        "Hello·World",
        "HelloWorld",
    }

    for _, text := range texts {
        if fuzzyMatch(pattern, text) {
            fmt.Printf("Matched: %s\n", text)
        } else {
            fmt.Printf("Not matched: %s\n", text)
        }
    }
}

解释

  1. 拆分模式字符串

    • 使用 strings.Split(pattern, "") 将模式字符串拆分为单个字符的切片。
  2. 构建正则表达式模式

    • 使用 regexp.QuoteMeta(part) 对每个字符进行转义,确保它们在正则表达式中被正确处理。
    • 使用 strings.Join(regexParts, [-\s·]?) 将这些字符连接起来,允许它们之间有可选的连字符、空白字符或 · 字符。
  3. 构建最终的正则表达式

    • 使用 fmt.Sprintf("^.*%s.*$", regexPattern) 构建最终的正则表达式,匹配包含模糊模式字符串的任意字符串。
  4. 进行匹配

    • 使用 regexp.MustCompile(finalPattern) 编译正则表达式。
    • 使用 re.MatchString(text) 进行匹配,返回匹配结果。

通过这种方式,你可以实现对包含特定子字符串的字符串进行模糊匹配查找,即使它们之间有空格、标点符号或其他字符,同时也匹配不包含这些字符的字符串。

输出

Matched: Hello-World
Matched: Hello World
Matched: Hello·World
Matched: HelloWorld

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2225281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[MoeCTF 2022]endian

查看发现是64位文件,且看到了amd64-64-little(这里是小端序) 所以我们要反向输入 对于整数 0x12345678,在小端序存储下的内存布局为: 地址 内容 低地址 0x78 0x56 0x34 高地址 0x12 查看main函数&#xff0c…

Python4

4. 更多控制流工具 除了刚介绍的 while 语句&#xff0c;Python 还用了一些别的。我们将在本章中遇到它们。 4.1. if 语句 if elif else if x<0: x 0 print(Negative changed to zero) elif x0: print( zero) else: print(More) 4.2. for 语句 Pyth…

游戏服务器被攻击有办法防护吗

游戏服务器受到攻击时比较常见的。就算是刚上线的游戏&#xff0c;都会有被攻击的时候。游戏服务器受到攻击的原因以及解决方案有哪些呢&#xff1f; 游戏服务器被攻击的原因有哪些呢&#xff1f; 1、常见的攻击&#xff0c;大部分来自于同行之间的恶意竞争&#xff0c;你的游…

Rust 力扣 - 3. 无重复字符的最长子串

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们需要记录当前子串的开始下标&#xff0c;一个哈希表记录字符和遍历过程中最后一次出现的索引 遍历字符串&#xff0c;如果在当前字符在哈希表中有记录&#xff0c;并且索引下标大于当前子串的开始下标&…

Lesson12---queue

Lesson12—queue 本篇博客介绍了cqueue的介绍使用以及模拟实现 文章目录 Lesson12---queue前言一、queue的成员函数1 queue2.empty3.size4.front5.back6.push7.pop 二、相关题目三、模拟实现完整代码 四、deque&#xff08;双端队列&#xff09;总结 前言 queue的文档:https:…

go高并发之路——本地缓存

一、使用场景 试想一个场景&#xff0c;有一个配置服务系统&#xff0c;里面存储着各种各样的配置&#xff0c;比如直播间的直播信息、点赞、签到、红包、带货等等。这些配置信息有两个特点&#xff1a; 1、并发量可能会特别特别大&#xff0c;试想一下&#xff0c;一个几十万…

CANopen中错误帧的制造和观测

本文讲述如何制造和观察CANopen中的错误帧&#xff08;Error frame&#xff09;&#xff0c;以Linux下的“VCAN0”为CAN接口来做测试&#xff0c;所以事先要先创建vcan0 一 制造错误帧 首先安装python CAN&#xff0c; pip3 install python-can然后参考python can的文档编写如…

Android View

前面我们了解了Android四大组件的工作流程&#xff0c;Android中还存在一个和四大组件地位相同的概念&#xff1a;View&#xff0c;用于向用户页面展示内容。我们经常使用的TextView、Button、ImageView控件等都继承于它&#xff0c;也会自定义View实现自定义效果。View类源码内…

2024CSP-J题目简析

扑克牌 1.题目大意&#xff1a;给定n张扑克牌和这n张扑克牌的花色和大小&#xff08;可能会有重复&#xff09;&#xff0c;需要输出还需要多少张牌才能凑齐一副扑克牌&#xff08;这里不考虑大小王&#xff0c;所以共52张&#xff09;。 2.思路概要&#xff1a;由于扑克牌会…

C++ | Leetcode C++题解之第513题找树左下角的值

题目&#xff1a; 题解&#xff1a; class Solution { public:int findBottomLeftValue(TreeNode* root) {int ret;queue<TreeNode *> q;q.push(root);while (!q.empty()) {auto p q.front();q.pop();if (p->right) {q.push(p->right);}if (p->left) {q.push(…

配置smaba (Linux与windows通信)

在Ubuntu上安装Samba是一个简单的过程。以下是详细的步骤&#xff0c;帮助你从安装到基本配置。 步骤1&#xff1a;更新软件包列表 首先&#xff0c;打开终端&#xff0c;确保你的软件包列表是最新的&#xff1a; sudo apt update 步骤2&#xff1a;安装 Samba 接下来…

若依学习 后端传过来的数据在控制台打印为空

导言: 在做若依二次开发时遇到个没见过的bug&#xff0c;用了一些时间排&#xff0c;发现有自己没学过的东西。所以记录一下。后端用的是c#的asp.net core 问题描述&#xff1a; 后端穿过来的有数据的参数(数组)roleIds在控制台打印为空 后端字段定义: 后端数据&#xff1a; 前…

centos-LAMP搭建与配置(论坛网站)

文章目录 LAMP简介搭建LAMP环境安装apache&#xff08;httpd&#xff09;安装mysql安装PHP安装php-mysql安装phpwind LAMP简介 LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写&#xff1a;Linux操作系统&#xff0c;网页服务器Apache&#xff0c;…

【LangChain系列3】【检索模块详解】

目录 前言一、LangChain1-1、介绍1-2、LangChain抽象出来的核心模块1-3、特点1-4、langchain解决的一些行业痛点1-5、安装 二、检索模块详解2-1、文档加载器2-1-1、Demo示例2-1-2、JSON加载2-1-3、CSV加载 2-2、文档转换器2-2-1、按字符进行拆分2-2-2、按代码分割2-2-3、Markdo…

arm 体系架构-过程调用标准AAPCS

一、什么是AAPCS&#xff1f; 旧时&#xff0c;ARM 过程调用标准叫做 APCS (ARM Procedure Call Standard)&#xff0c;Thumb的过程调用标准为 TPCS。如今这两种叫法已经废弃&#xff0c;统一称作 AAPCS (Procedure Call Standard for the ARM Architecture)。 AAPCS 是 ARM …

UE5之5.4 第三人称示例代码阅读

第三人称的代码相对第一人称少了很多&#xff0c;只有一个移动跳跃的能力 构造函数&#xff0c;添加角色的移动属性&#xff0c;限制了当controller移动角色不会乱转&#xff0c;然后创建了一个相机杆&#xff0c;创建了一个跟随相机&#xff0c;绑到相机杆上 然后在这个函数设…

用二分法查找有序容器的插入点

例子&#xff1a; int main() {vector<int> vec { 1,2,3,4,5,7,8,9 };auto n alg.find_binary_insert_pos(vec.begin(), vec.end(), 6);vec.insert(vec.begin() n, 6);_pn(vec);list<int> lst { 1,10,11,9,5 };for (auto& v : lst) {//添加不存在的元素au…

241024-Ragflow离线部署Docker-Rootless环境配置修改

A. 最终效果 B. 文件修改 docker-compose.yml include:- path: ./docker-compose-base.ymlenv_file: ./.envservices:ragflow:depends_on:mysql:condition: service_healthyes01:condition: service_healthyimage: ${RAGFLOW_IMAGE}container_name: ragflow-serverports:- ${…

D50【python 接口自动化学习】- python基础之类

day50 init方法 学习日期&#xff1a;20241027 学习目标&#xff1a;类 -- 64 init方法&#xff1a;如何为对象传递参数&#xff1f; 学习笔记&#xff1a; 魔术方法 init方法 class Klass(object):# 定义初始化方法&#xff0c;类实例化时自动进行初始化def __init__(self…

autMan框架的指令转换功能学习

以正则表达式为基础 一、基本用法【简单替换】 示例1&#xff1a; 匹配表达式&#xff1a;激活 结果表达式&#xff1a;咖啡码 效果&#xff1a;只要命令中包含“激活”这两个字&#xff0c;就会将命令中所有的“激活”替换为“咖啡码”&#xff0c;即你从后台看到收到的命令是…