sed awk 第二版学习(二)—— 正则表达式语法

目录

一、表达式

二、成行的字符

1. 反斜杠

2. 通配符

3. 编写正则表达式

4. 字符类

(1)字符的范围

(2)排除字符类

(3)POSIX 字符类补充

5. 重复出现的字符

6. 匹配单词

7. gres 替换脚本

8. 限制范围


        在计算机术语中,表达式是某些需要被计算的东西。一个表达式描述一种结果。正则表达式描述了模式或特殊的字符序列,尽管没有必要指定一个精确的序列。例如:

^  *.*

        该表达式使用元字符(metacharacter)(也叫通配符)和空格,匹配一个具有一个或多个前导空格的行。

        grep、sed、awk 都使用正则表达式,但这三个程序并不能完全使用正则表达式语法中的所有元字符。为了理解正则表达式语法,必须了解由不同的元字符执行的功能。

一、表达式

        一个正则表达式描述了一种模式或字符序列。字符串连接是每个正则表达式的基本操作,也就是,一个模式匹配相邻的一系列字符。例如:

ABE

        每个字面字符都是一个正则表达式,它只匹配那个单独的字符。这个表达式描述了“B 跟着 A,E 跟着 B”,或者简单称为“字符串 ABE”。术语“字符串”意味着每个字符都与它前面的字符相连接。正则表达式区分大小写,因此“A”不匹配“a”。sed 和 awk 为使用正则表达式提供了不区分大小写的选项。

        接受正则表达式的程序必须首先解析正则表达式的语法来产生一个模式。然后逐行读取输入来尝试匹配该模式。输入行是一个字符串,要看字符串与模式是否匹配,程序将字符串的第一个字符与模式的第一个字符进行比较。如果匹配就比较第二个字符。无论何时只要匹配失败,就返回并从字符串中这个字符后面的字符重新开始匹配。下图说明了这个过程,在输入行上尝试匹配模式“abe”。


解释正则表达式

        正则表达式不只限于文字字符。例如元字符句点(.)可以作为“通配符”匹配任何单个字符。元字符星号(*)用于与它前面的正则表达式的零个、一个或多个匹配,该表达式通常是一个字符。星号元字符本身不匹配任何字符,它用于修饰它前面的内容。这与它在 shell 中的含义不同。正则表达式 .* 匹配任意数目的字符,而在 shell 中,* 本身就具有这种含义。* 作为一个 shell 元字符,表示“零或多个字符”。

        “.”和“*”代表了元字符的两个基本类型:能够被看做单个字符的元字符和被看做如何修饰前面的字符的元字符。使用元字符可以扩展或限制可能的匹配,从而更多地控制匹配什么和不匹配什么。

二、成行的字符

        表达式中的两个基本元素是:

  1. 以一个字面值或变量表示的值。
  2. 一个操作符。

        在正则表达式中,除下表中的元字符外,任意字符都被解释为只匹配它本身的字面值。

特殊字符

用途

.

匹配除换行符以外的任意单个字符。在 awk 中,句点也能匹配换行符。

*

匹配任意多个(包括零个)在它前面的单个字符,或由正则表达式指定的字符。

[...]

匹配方括号中的字符类中的任意一个。如果方括号中的第一个字符为脱字符(^),则表示否定匹配,即匹配除了换行符和类中列出的那些字符以为的所有字符。在 awk 中,也匹配换行符。连字符(-)用于表示字符类的范围。如果类中的第一个字符为右方括号(])则表示它是类的成员。所有其它的元字符在被指定为类中的成员时都会失去它们原来的含义。

^

如果作为正则表达式的第一个字符,则表示匹配行的开始。在 awk 中匹配字符串的开始,即使字符串包含嵌入的换行符。

$

如果作为正则表达式的最后一个字符,则表示匹配行的结尾。在 awk 中匹配字符串的结尾,即使字符串包含嵌入的换行符。

\{n,m\}

匹配它前面某个范围内单个字符,或由正则表达式指定的字符的出现次数。\{n\}匹配n次出现,\{n,\}至少匹配n次出现,\{n,m\}匹配n和m之间的任意次出现。

\

转义随后的特殊字符。

+

匹配前面的正则表达式的一次或多次出现。

?

匹配前面的正则表达式的零次或一次出现。

|

指定可以匹配其前面的或后面的正则表达式(替代)。

()

对正则表达式分组。

{n,m}

匹配它前面某个范围内单个字符,或由正则表达式指定的字符的出现次数。{n}匹配n次出现,{n,}至少匹配n次出现,{n,m}匹配n和m之间的任意次出现。(用于 POSIX 的 egrep 和 POSIX awk 而不是传统的 egrep 或 awk。)

元字符汇总

        元字符在正则表达式中有特殊的含义。下面介绍每个元字符的用法。

1. 反斜杠

        元字符反斜杠(\)将元字符转换成普通字符(或将普通字符转换成元字符)。它强制将任意元字符解释为普通字符,以便匹配该字符本身。

# 转义句点:
\.# 转义反斜杠:
\\# 将普通字符解释为元字符:
\(\) \{\} \n

2. 通配符

        句点(.)代表除换行符以外的任意字符的通配符(在 awk 中,句点甚至可以匹配嵌入式换行符),通常放在字面字符或其它元字符的前面或后面。

        匹配 Plymouth 后跟任意一个字符:

$ grep Plymouth. list 
John Daggett, 341 King Road, Plymouth MA

        本例中这个表达式与固定的字符串模式“Plymouth”具有相同的匹配:

$ grep Plymouth list
John Daggett, 341 King Road, Plymouth MA

        如果句点前的字符出现在行尾,因为句点不匹配换行符,所以不匹配那一行:

$ grep MA. list 
$ grep MA list 
John Daggett, 341 King Road, Plymouth MA
Eric Adams, 20 Post Road, Sudbury MA
Sal Carpenter, 73 6th Street, Boston MA

3. 编写正则表达式

        正则表达式允许编写简单或复杂的模式描述,而使编写正则表达式困难的因素是应用的复杂性:模式出现在各种不同的情况和上下文中。复杂性是语言本身所固有的。

        编写正则表达式的过程涉及 3 个步骤:

  1. 知道要匹配的内容以及它如何出现在文本中。
  2. 编写一个模式来描述要匹配的内容。
  3. 测试模式来查看它匹配的内容。

        这个过程实质上与程序员开发程序的过程相似。步骤 1 可以当做规范,它反映理解要解决的问题以及如何解决它。步骤 2 类似于编写程序代码,而步骤 3 相当于运行程序并根据规范测试它。步骤 2 和步骤 3 需重复进行,直到程序令人满意为止。

        对匹配描述进行测试可以确保这个描述和所期待的一样。仔细检查测试的结果,比较输出和输入,可以大大提高对正则表达式的理解。可以按下面的方式解析模式匹配的结果:

  • Hits(命中):要匹配的行。
  • Misses(未命中):不要匹配的行。
  • Omissions(遗漏):没有匹配但需要匹配的行。
  • False alarms(假报警):不要匹配但却匹配了的行。

4. 字符类

        可以列出要匹配的字符,使用方括号元字符([])将字符列表括起来,其中每个字符占据一个位置。这在处理大小写字符时很有用。例如:

[Ww]hat

        这个正则表达式可以匹配“what”或“What”。它匹配包含这 4 个字符的字符串的任意行。如果想提取包含 .H1、.H2、.H3 等结构化标题宏的行,可以使用下面的正则表达式:

\.H[12345]

        可以使用字符类在 UNIX 命令中指定文件名。例如为了从一组以章节为文件名的文件中提取标题可能输入:

$ grep '\.H[123]' ch0[12]

        注意必须用引号引住其中的模式,以便把它传递给 grep 而不是由 shell 解释。下面列出了方括号中具有特殊含义的字符。

  • \:转义任意特殊字符(只用于 awk 中)。
  • -:当它不在第一个或最后一个位置时,表示一个范围。
  • ^:仅当在第一个位置时表示反转匹配。

(1)字符的范围

        连字符(-)用于指定一个字符范围。每个字符类都匹配单个字符,如果指定多个类,可以描述多个连续的字符。

        匹配所有大写英文字母:

[A-Z]

        匹配数字:

[0-9]

        匹配数字、小写字母、问号、逗号、句点、分号、冒号、单引号或双引号:

[0-9a-z?,.;:'"]

        匹配“任意后面跟有句点、问号或感叹号的小写或大写字母”:

[a-zA-Z][.?!]

        如果闭括号(])是作为类中的第一个字符出现,那么它就被解释为类的一个成员。如果连字符在一个类中是第一个或最后一个字符,则失去其特殊含义。

        匹配算数操作符:

[-+*/]

        匹配 MM-DD-YY 或 MM/DD/YY 两种日期格式:

[0-1][0-9][-/][0-3][0-9][-/][0-9][0-9]

(2)排除字符类

        类中作为第一个字符的脱字符(^)将类中的所有字符都排除在被匹配之外,或者说匹配除换行符(awk 中换行符也可以被匹配)以外的没有列在方括号中的任意字符。

        匹配任意非数字字符:

[^0-9]

        匹配非小写元音:

[^aeiou]

        匹配字符串“.DS”其后依次跟随一个空格、一个双引号、一个除了字符 1 以外的单个字符和一个双引号。

\.DS "[^1]"

(3)POSIX 字符类补充

        POSIX 标准定义了两类正则表达式:基本的正则表达式(BRE),grep 和 sed 使用;扩展的正则表达式,egrep 和 awk 使用。

        为了适应非英文环境,POSIX 标准增强了匹配不在英文字母表中的字符的字符类的功能。例如,法文 è 是一个字母字符,但使用典型的字符类 [a-z] 不匹配它。该标准提供了附加的字母序列,当匹配和排序字符串数据时,这些字符应该被作为单个单元看待。

        POSIX 还改变了常用的术语。“字符类”在 POSIX 标准中称为“括号表达式”。在括号表达式中,除字面字符外,还可以有如下标记:

  • 字符类。由 [: 和 :] 包围 的关键字组成的 POSIX 字符类。关键字描述了不同的字符类,例如文字字符、控制字符等等。
  • 排序符号。排序符号是多字符的序列,表示这些字符应该被看做是一个单元。它由 [. 和 .] 包围的字符组成。
  • 等价类。等价类列出了应该看做是等价的字符集。例如 e 和 è。它由地区化的字符元素(由 [= 和 =] 包围)组成。

        所有这三种结构都必须出现在括号表达式的方括号中。例如 [[:alpha:]!] 匹配任意单个字母字符或感叹号,[[.ch.]] 匹配整理元素 ch,但不只匹配字母 c 或字母 h。在法语地区中,[[=e=]] 可以匹配任意 e、è 或 é。下表列出了类及其匹配字符。

匹配字符

[:alnum:]

可打印字符,包括空白字符

[:alpha:]

字母字符

[:blank:]

空格和制表符

[:cntrl:]

控制字符

[:digit:]

数字字符

[:graph:]

可打印的和可见的非空格字符

[:lower:]

小写字符

[:print:]

可打印字符,包括空白字符

[:punct:]

标点符号字符

[:space:]

空白字符

[:upper:]

大写字符

[:xdigit:]

十六进制数

POSIX字符类

        GNU awk 和 GNU sed 支持字符类符号,但不支持另外两个括号符号。

5. 重复出现的字符

        星号(*)元字符表示它前面的正则表达式可以出现零次、一次或多次。可以使用星号元字符匹配出现在引号中的单词。

        不管单词 hypertext 是否出现在引号中都会被匹配。

"*hypertext"*

        看一系列数字:

1
5
10
50
100
500
1000
5000

        匹配所有行:

[15]0*

        匹配除前面两行以外的所有行:

[15]00*

        第一个 0 是字面值,第二个由星号修饰。常使用类似的方法匹配一个或多个(而不是零个或多个)空格:

  *

        当星号元字符前面有句点元字符时,表示匹配任意数目的字符。这可用于标识两个固定的字符串之间的字符的跨度。使用“.*”进行匹配的范围总是最大的(贪婪模式)。

        匹配引号中的任意字符串:

".*"

        匹配带有 <> 标记的所有行:

grep '<.*>' sample

        看下面的 5 行示例文本:

I can do it
I cannot do it
I can not do it
I can't do it
I cant do it

        匹配以上语句中的否定语句,但不匹配肯定语句:

can[ no']*t

        匹配所有行:

can.*t

        技术术语“closure(闭合)”有匹配“零次或多次”的能力。egrep 和 awk 使用的元字符扩展提供了几个非常有用的 closure 的变化。加号(+)匹配其前面正则表达式的一次或多次出现。问号(?)匹配零次或一次出现。不要和 shell 中的 ? 通配符混淆。shell 中的 ? 表示单个字符,等效于正则表达式中的“.”。

6. 匹配单词

        匹配 book,包括单数和复数:

$ cat bookwords 
This file tests for book in various places, such as
book at the beginning of a line or
at the end of a line book
as well as the plural books and
handbooks. Here are some
phrases that use the word in different ways:
"book of the year award"
to look for a line with the word "book"
A GREAT book!
A great book? No.
told them about (the books) until it
Here are the books that you requested
Yes, it is a good book for children
amazing that it was called a "harmful book" when
once you get to the end of the book, you can't believe
A well-written regular expression should
avoid matching unrelated words,
such as booky (is that a word?)
and bookish and
bookworm and so on.$ egrep "(^| )[\"[{(]*book[]})\"?\!.,;:'s]*( |$)" bookwords
This file tests for book in various places, such as
book at the beginning of a line or
at the end of a line book
as well as the plural books and
"book of the year award"
to look for a line with the word "book"
A GREAT book!
A great book? No.
told them about (the books) until it
Here are the books that you requested
Yes, it is a good book for children
amazing that it was called a "harmful book" when
once you get to the end of the book, you can't believe

        书中给出的正则表达式是“(^| )[\"[{(]*book[]})\"?\!.,;:'s]*( |$)”,很麻烦。试了一下,egrep 支持 \b,用这个很简单:

$ egrep '\bbook(s)?\b' bookwords

7. gres 替换脚本

$ cat gres 
if [ $# -lt "3" ]
then
echo Usage: gres pattern replacement file
exit 1
fi
pattern=$1
replacement=$2
if [ -f $3 ]
then
file=$3
else
echo $3 is not a file.
exit 1
fi
A="`echo | tr '\012' '\001' `"
sed -e "s$A$pattern$A$replacement$A" $file$ ./gres "A*Z" "00" test
All of us, including 00ippy, our dog
Some of us, including 00ippy, our dog

8. 限制范围

        匹配第一个引号里的内容:

$ cat sampleLine
.Se "Appendix" "Full Program Listings"$ ./gres '"[^"]*"' '00' sampleLine
.Se 00 "Full Program Listings"

        匹配两个数字之间至少有 5 个句点,并将句点替换为连字符:

$ cat sample
1........5
5........10
10.......20
100......200$ sed 's/\([0-9][0-9]*\)\.\{5,\}\([0-9][0-9]*\)/\1-\2/' sample
1-5
5-10
10-20
100-200

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

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

相关文章

使用 Rust 和 Bevy 创建你的第一个三维渲染应用程序

为什么选择 Rust 进行三维开发&#xff1f; Rust 的特点使其非常适合用于三维开发&#xff1a; 内存安全性&#xff1a;Rust 的所有权系统和严格的编译器检查可以防止常见的内存错误&#xff0c;如空指针和数据竞争。高性能&#xff1a;Rust 是一门系统编程语言&#xff0c;能…

力扣167.两数之和II-输入有序数组

import java.util.HashMap; //法1&#xff1a;哈希表 class Solution {public int[] twoSum(int[] numbers, int target) {HashMap<Integer, Integer> map new HashMap<Integer, Integer>();for(int i 0; i < numbers.length; i) {if (map.containsKey(target…

2024-09-02 Ubuntu固定USB串口名(包括1拖N的USB串口)

在运行Ubuntu系统的开发板上,如果使用可插拔的USB串口,有时候程序正在运行时,如果突然连接传感器的USB串口设备被插拔了一下,这时,会发现系统中的USB串口名发生了改变。例如,插拔之前是/dev/ttyUSB0,插拔之后变成了/dev/ttyUSB3。发生这种情况的时候,有时候会导致程序无…

python出现远程服务器访问不了Hugging Face

OSError: We couldn’t connect to ‘https://huggingface.co’ to load this file, couldn’t find it in the cached files and it looks like stabilityai/sd-turbo is not the path to a directory containing a file named tokenizer/config.json. 解决方法&#xff1a; …

关于VUE3开发频繁引入ref,reactive,computed等基础函数。

利用unplugin-auto-import插件可以避免频繁引入ref&#xff0c;reactive&#xff0c;computed等基础函数。 1.安装unplugin-auto-import依赖 npm i -D unplugin-auto-import 2.在vite.config.ts中注入依赖 效果

关于主流电商平台|淘宝|拼多多|抖音|1688官方平台接口的接入和返回

taobao.trades.sold.get( 查询卖家已卖出的交 搜索当前会话用户作为卖家已卖出的交易数据&#xff08;只能获取到三个月以内的交易信息&#xff09; 1. 返回的数据结果是以订单的创建时间倒序排列的。 2. 返回的数据结果只包含了订单的部分数据&#xff0c;可通过taobao.trade…

C++系列-STL容器中的for循环遍历方式

STL容器中的for循环遍历方式 普通的for循环利用迭代器for循环for循环新用法 for (auto i_st : st)for_each循环 淮上喜会梁川故友 韦应物 江汉曾为客&#xff0c;相逢每醉还。 浮云一别后&#xff0c;流水十年间。 欢笑情如旧&#xff0c;萧疏鬓已斑。 何因不归去&#xff0c;淮…

前端宝典二十六:vue3的新特性

一、Vue2处理响应式的源码方式&#xff1a; const initData {value: 1 } const data {};Object.keys(initData).forEach(key > {Object.defineProperty(data, key, {get() {return initData[key]},set(value) {initData[key] value}}) })console.log(data.value) // 1 …

代码随想录Day 32|leetcode题目:501.斐波那契数、70.爬楼梯、746.使用最小花费爬楼梯

提示&#xff1a;DDU&#xff0c;供自己复习使用。欢迎大家前来讨论~ 文章目录 动态规划理论基础一、理论基础1.1 什么是动态规划1.2 动态规划的解题步骤1.3 动态规划应该如何debug 二、题目题目一&#xff1a; 509. 斐波那契数解题思路&#xff1a;动态规划递归解法 题目二&a…

设计模式学习-责任链模式

概念 使多个对象都有机会处理请求&#xff0c;从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有对象处理它为止. 代码编写 using UnityEngine; using System.Collections; public class ChainOfResp…

《从C/C++到Java入门指南》- 26.record 类+多态

record 类多态 前言 由于 record 类比较简单&#xff0c;将他和多态放在一节中。 record 类 final类是从 Java 16开始才正式发布的&#xff0c;可以理解为一个final class&#xff0c;提供了一种更简洁紧凑的定义final类的方式。 public record Clock(int hours, int minu…

【golang-入门】环境配置、VSCode开发环境配置

golang介绍基础信息 windows环境配置安装包下载安装环境变量设置检查 VSCode开发配置插件配置在 Visual Studio Code 中安装通义灵码go hello word 参考资料 golang介绍 基础信息 golang官网&#xff1a;https://go.dev/golang学习网&#xff1a;https://studygolang.com/使用…

【嵌入式学习笔记】STM32中断配置及相关知识

中断 中断配置 1、使能GPIO 2、使能系统时钟 3、配置引脚 4、配置映射关系 5、配置EXTI 6、启用并设置EXTI #include "stm32f4xx.h" // Device header #include "sys.h" #include "delay.h" #include "led.h"…

ARM基础知识---CPU---处理器

目录 一、ARM架构 1.1.RAM---随机存储器 1.2.ROM---只读存储器 1.3.flash---闪存存储器 1.4.时钟&#xff08;振晶&#xff09; 1.5.复位 二、CPU---ARM920T 2.1.R0~R12---通用寄存器 2.2.PC程序计数器 2.3.LR连接寄存器 2.4.SP栈指针寄存器 2.5.CPSR当前程序状态寄存…

测试:TestGRPCDiscovery

目录 测试:TestGRPCDiscovery 类定义 方法 async def asyncSetUp(self): async def asyncTearDown(self): async def test_discovery(self): 总结 这是一个关于算力共享中环形结构通讯机制的项目图的功能模型解释。以下是根据所给信息对项目功能的概述: 项目结构: 项…

Windows 下载安装RabbitMQ

环境描述 windows10 Erlang 26.2.x 版本 RabbitMQ 3.13.7 因为RabbitMQ是Erlang语言开发的&#xff0c;所以必须安装 Erlang RabbitMQ官网链接: https://www.rabbitmq.com/docs/which-erlang 1.下载并安装Erlang 26.2.5 1.1下载Erlang 26.2.5 https://erlang.org/dow…

深度强化学习算法(四)(附带MATLAB程序)

深度强化学习&#xff08;Deep Reinforcement Learning, DRL&#xff09;结合了深度学习和强化学习的优点&#xff0c;能够处理具有高维状态和动作空间的复杂任务。它的核心思想是利用深度神经网络来逼近强化学习中的策略函数和价值函数&#xff0c;从而提高学习能力和决策效率…

鸿誉移民:定制化移民服务,吹响全球高效率移民的嘹亮号角!

鸿誉移民&#xff1a;定制化移民服务&#xff0c;吹响全球高效率移民的嘹亮号角&#xff01; 作为国内知名海外移民服务机构&#xff0c;鸿誉移民历经多年行业沉淀&#xff0c;拥有着极其丰富的移民咨询以及移民办理经验&#xff0c;并以咨询及时精准&#xff0c;签证快捷、通…

【数据结构】Map的使用与注意事项

文章目录 概念模型Map 的使用put() 和 get()getOrDefault()remove()keySet()entrySet() 注意事项 概念 Map 和 set 是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例化子类有关。 以前常见的搜索方式有&#xff1a; 直接遍历&#xff0c;时间…

URP简洁的instance的写法

材质还是要开启enable instance&#xff0c;这是上一次的写法 https://dbbh666.blog.csdn.net/article/details/136644181 最近发现更适合我个人的习惯的写法 就是代码控制这个整个过程 C#代码是这样的&#xff0c;获取一个mesh&#xff0c;获取每个mesh的transform&#xff0c…