iOS高级强化--015:Regular Expressions

正则表达式学习

正则表达式:是处理字符串的⼀种表达⽅式。提供了⼀种从⼀组字符串中
选择特定字符串的机制

POSIX规范定义了UNIX操作系统应当⽀持的功能,POSIX规范的正则表达式:

  • BRE:(Basic Regular Expression)基本型正则表达式
  • ERE:(Extended Regular Express)扩展型正则表达式

BREERE⼆者的区别,简单的说就在于(){}+?|7个特殊字符的使⽤⽅法上:

  • BRE中,如果想要这些字符表示特殊的含义,就需要把它们转义。元字符 (){}+?|必须转义之后才具有特殊含义,如\+\?\|,⽽且也⽀持\1\2之类反向引⽤
  • 反之,在ERE中,如果要这些字符不表示特殊的含义,就需要把它们转义。虽然BRE名为“基本”⽽ERE名为“扩展”,但ERE并不要求兼容BRE的语法,⽽是⾃成⼀体
  • BRE中的特殊字符:.\[^$*
  • ERE中的特殊字符多了7个,即:.\[^$*(){}+?|

正则表达式与通配符没有任何关系,不是包含关系

  • 通配符,是Shell提供的功能
  • 正则表达式只是⽤来处理字符串

如何学习正则表达式?

  • 背,一些特殊字符的意义
  • 实际练习

案例:

⼀个常⻅的正则表达式

^1[3-9](\d{9})$
  • ^:锚点操作符,匹配字符串的开头
  • [3-9]:列表操作符,只匹配中括号中的⼀个字符。-:范围操作符指定范围
  • \d:代表0-9数字
  • {9}:间隔运算符,匹配前⼀个元素⼏次
  • (\d{9}):分组/捕获组,定义⼀个⼦表达式
  • $:锚点操作符,匹配字符串的结尾
特殊符号的意义
直抒胸臆操作符:
类别 匹配类型 匹配字符
Cat 字符串Cat,属于串联 Cat,不能匹配Catt
C 字符C C
渣男操作符:
类别 匹配类型 匹配字符
. 匹配所有的字符,除了newlinenull 通吃lsp
重复操作符:
类别 匹配类型
* 匹配前⼀个元素0次或多次
+ 匹配前⼀个元素1次或多次
? 匹配前⼀个元素0次或1
间隔操作符 { ... }:
类别 匹配类型
{count} 匹配前⼀个元素count
{min,} 匹配前⼀个元素⾄少min
{min, max} 匹配前⼀个元素⾄少min次,⾄多max
备胎操作符:
类别 匹配类型 匹配字符
| 匹配前⼀个表达式或后⼀个表达式 在吗?我怀孕了
列表操作符 [ ... ] and [^ ... ] :

⼀般操作符在列表操作符⾥会失去特殊意义,除了:

类别 匹配类型
] 结束列表,[]]
\ 转义字符
[: 字符类别操作符开始
:] 字符类别操作符结束
- 范围操作符,0-9
字符类别操作符 [: ... :] :
类别 匹配类型 匹配字符
[:alnum:] [A-Za-z0-9] 数字和字⺟字符
[:alpha:] [A-Za-z] 字⺟字符
[:blank:] [ \t] 空格和TAB
[:cntrl:] [\x00-\x1F\x7F] 控制符
[:digit:] [0-9] 数字
[:graph:] [\x21-\x7E] 可视字符
[:lower:] [a-z] ⼩写字⺟字符
[:print:] [\x20-\x7E] 可视字符和空格(ASCII040-0176
[:punct:] ][!"#$%&'()*+,./:;<=>?@\^_`{|}~-] 标点符号
[:space:] [\t\r\n\v\f] 空⽩字符
[:upper:] [A-Z] ⼤写字⺟字符
[:xdigit:] [A-Fa-f0-9] ⼗六进制字符
特殊字符类别操作符:
类别 匹配类型 匹配字符
\w [:alnum:] 数字和字⺟字符
\d [:digit:] 数字
\W [^[:alnum:]] 除了数字和字⺟字符
\B [^[:digit:]] 除了数字
\< ^ 匹配字符串的开头
\> $ 匹配字符串的结尾
\b to\b匹配to!,但不匹配tomorrow 匹配单词边界字符
范围操作符:
类别 匹配类型
- 匹配指定范围,但是需在列表中使⽤,并指定范围,如[a-z][-az]或者[az-]表示匹配字⺟az还有-
锚点操作符:
类别 匹配类型
^ 匹配字符串的开头,需在开头
$ 匹配字符串的结尾或者换⾏符的前⼀个位置,需在结尾
  • 如果^在列表操作符中使⽤,并且在⾸位,代表取反
操作符优先级:
优先级(由⾼到低) 操作符
归类相关的括号符号 [::]
转义字符 \<特殊字符>
括号表达 []
分组 ()
单字符重复 * + ?{m, n}
串联 .
锚点 ^ $
备选 |
基础示例
grep
  • -v:逆转显示
  • -i:忽略⼤⼩写
  • -A:向上显示⼏⾏
  • -B:向下显示⼏⾏
  • -E:启⽤扩展
  • —color:显示颜⾊
egrep
  • 使用grep -E,启用ERE扩展型正则表达式

案例:

打开test.swift文件,写入以下文本:

struct LGTeacher {
   let name: String
   let class: String
   let credit:String
   let description: String
}

struct LGTeachers {
   let name: String
   let class: String
   let credit:String
   let description: String
}

extension LGTeacher {
   static var all: [LGTeacher] {
       [ LGTeacher(
           name: "Cooci",
           license: "http://creativecommons.org/licenses/by-sa/3.0",
           credit: "http://commons.wikimedia.org/wiki/User:Lin%C3%A91",
           description: "Basil is commonly used fresh in cooked recipes. In general, it is added at the last moment, as cooking quickly destroys the flavor. The fresh herb can be kept for a short time in plastic bags in the refrigerator, or for a longer period in the freezer, after being blanched quickly in boiling water. The dried herb also loses most of its flavor, and what little flavor remains tastes very different.9oo *oo"
       ),
       LGTeacher(
           name: "Kody",
           license: "http://creativecommons.org/licenses/by-sa/3.0",
           credit: "http://commons.wikimedia.org/wiki/User:Lin%C3%A91",
           description: "Saffron's aroma is often described by connoisseurs as reminiscent of metallic honey with grassy or hay-like notes, while its taste has also been noted as hay-like and sweet. Saffron also contributes a luminous yellow-orange colouring to foods. Saffron is widely used in Indian, Persian, European, Arab, and Turkish cuisines. Confectioneries and liquors also often include saffron."
       ),
       LGTeacher(
           name: "Hank",
           license: "http://creativecommons.org/licenses/by-sa/3.0",
           credit: "http://commons.wikimedia.org/wiki/User:Raul654",
           description: "Marjoram is used for seasoning soups, stews, dressings and sauce. Majorana has been scientifically proved to be beneficial in the treatment of gastric ulcer, hyperlipidemia and diabetes. Majorana hortensis herb has been used in the traditional Austrian medicine for treatment of disorders of the gastrointestinal tract and infections."
       ),
       LGTeacher(
           name: "CC",
           license: "http://www.gnu.org/licenses/old-licenses/fdl-1.2.html",
           credit: "http://commons.wikimedia.org/wiki/User:Fir0002",
           description: "The leaves, both fresh and dried, are used in traditional Italian cuisine. They have a bitter, astringent taste and are highly aromatic, which complements a wide variety of foods. Herbal tea can be made from the leaves. When burnt, they give off a mustard-like smell and a smell similar to burning wood, which can be used to flavor foods while barbecuing. Rosemary is high in iron, calcium and vitamin B6.")
       ,
       LGTeacher(
           name: "Cat",
           license: "http://commons.wikimedia.org/wiki/File:AniseSeeds.jpg",
           credit: "http://commons.wikimedia.org/wiki/User:Ben_pcc",
           description: "Anise is sweet and very aromatic, distinguished by its characteristic flavor. The seeds, whole or ground, are used in a wide variety of regional and ethnic confectioneries, including black jelly beans, British aniseed balls, Australian humbugs, and others. The Ancient Romans often served spiced cakes with aniseseed, called mustaceoe at the end of feasts as a digestive. "
       )
       ]
   }
}

匹配包含LG的内容

grep "LG" test.swift
-------------------------
struct LGTeacher {
struct LGTeachers {
extension LGTeacher {
   static var all: [LGTeacher] {
       [ LGTeacher(
       LGTeacher(
       LGTeacher(
       LGTeacher(
       LGTeacher(

匹配包含LG的内容,将每一行的匹配结果,都向下多显示一行

grep "LG" test.swift -A 1
-------------------------
struct LGTeacher {
   let name: String
--
struct LGTeachers {
   let name: String
--
extension LGTeacher {
   static var all: [LGTeacher] {
       [ LGTeacher(
           name: "Cooci",
--
       LGTeacher(
           name: "Kody",
--
       LGTeacher(
           name: "Hank",
--
       LGTeacher(
           name: "CC",
--
       LGTeacher(
           name: "Cat",

匹配包含LG的内容,将每一行的匹配结果,上下各多显示一行

grep "LG" test.swift -A 1 -B 1
-------------------------

struct LGTeacher {
   let name: String
--
--

struct LGTeachers {
   let name: String
--
--

extension LGTeacher {
   static var all: [LGTeacher] {
       [ LGTeacher(
           name: "Cooci",
--
--
       ),
       LGTeacher(
           name: "Kody",
--
--
       ),
       LGTeacher(
           name: "Hank",
--
--
       ),
       LGTeacher(
           name: "CC",
--
--
       ,
       LGTeacher(
           name: "Cat",

匹配包含lgteacher的内容,忽略大小写

grep "lgteacher" test.swift -i
-------------------------
struct LGTeacher {
struct LGTeachers {
extension LGTeacher {
   static var all: [LGTeacher] {
       [ LGTeacher(
       LGTeacher(
       LGTeacher(
       LGTeacher(
       LGTeacher(

匹配过滤LGTeacher后的内容

grep "LGTeacher" test.swift -v

匹配包含LGTeacher的内容,但不匹配LGTeachers

grep "LGTeacher[^s]" test.swift
-------------------------
struct LGTeacher {
extension LGTeacher {
   static var all: [LGTeacher] {
       [ LGTeacher(
       LGTeacher(
       LGTeacher(
       LGTeacher(
       LGTeacher(

匹配包含oo的内容

grep "oo" test.swift

匹配包含oo的内容,过滤前面由小写字母开头的内容

grep "[^a-z]oo" test.swift
//或者
grep "[^[:lower:]]oo" test.swift

匹配包含oo的内容,只保留数字或符号开头的内容

grep "[^A-Za-z]oo" test.swift

匹配包含oo的内容,只保留数字开头的内容

grep "[0-9]oo" test.swift
//或者
grep "\doo" test.swift

匹配包含oo的内容,只保留符号开头的内容

grep "[^A-Za-z0-9]oo" test.swift
//或者
grep "\Woo" test.swift

匹配包含oo的内容,过滤前面由符号开头的内容

grep "[A-Za-z0-9]oo" test.swift
//或者
grep "\woo" test.swift

使用.占中间两位,匹配C开头,ci结尾的内容

grep "C..ci" test.swift
-------------------------
name: "Cooci",

匹配C开头,使用.占后两位的内容

grep "C.." test.swift
  • .:匹配所有的字符,除了newlinenull

匹配Co开头,使用*占后一位的内容

grep "Co*" test.swift
  • *:匹配前⼀个元素0次或多次

匹配Coo开头,使用*占后一位的内容

grep "Coo*" test.swift

匹配C开头,后面接两个o的内容

grep -E "Co{2}" test.swift
-------------------------
name: "Cooci",
  • 间隔操作符{ ... },是ERE中支持的特殊符号。grep命令支持ERE表达式,需要增加-E参数
分组与向后引⽤

分组\捕获组操作符(( ... ) or \( ... \))

  • 定义⼀个⼦表达式。正则表达式将此序列视为⼀个单元。圆括号在整体匹配完后进⾏匹配
  • 可以配合反向引⽤操作符,重复使⽤分组匹配的结果

反向引⽤操作符(\digit)

  • 反向引⽤操作符由\数字表示,数字需介于1-9,代表引⽤那个分组的匹配结果

案例1:

匹配包含oo的内容,只保留数字开头的内容,使用(\d)进行分组

grep -E "(\d)oo" test.swift
  • 分组( ... ),是ERE中支持的特殊符号。grep命令支持ERE表达式,需要增加-E参数

案例2:

通过\1获取第一个分组内容

grep -E "description(.*)(\1)" test.swift
  • 反向引⽤操作符(\digit),代表引⽤那个分组的匹配结果
\ 字符

以下内容在部分语⾔中不⽀持

每种环境,⽆论是PythonPerlJavaC#Ruby还是其他,在实现正则表达式时都有特殊的差别。Swift也不例外

Objective-CSwift都要求您转义⽂字字符串中的特殊字符(即,在它们
前⾯加反斜杠\字符)。反斜杠本身就是这样的特殊字符之⼀。由于⽤于创建
正则表达式的模式也是字符串,因此会增加复杂性,因为在使⽤Stringand
需要转义反斜杠字符NSRegularExpression

这意味着标准正则表达式\.将出现\\.在您的Swift(或Objective-C)代码中

  • ⽂字\\.定义了⼀个类似于以下字符串:\.
  • 正则表达式\.然后将匹配单个句点字符
贪婪模式

贪婪模式、勉强模式与侵占模式:

贪婪匹配 勉强匹配 侵占匹配 作⽤
X? X?? X?+ 匹配X零次或⼀次
X* X*? X*+ 匹配X零次或多次
X+ X+? X++ 匹配X⼀次或多次
X{n} X{n}? X{n}+ 匹配Xn
X{n,} X{n,}? X{n,}+ 匹配X⾄少n
X{n,m} X{n,m}? X{n,m}+ 匹配X⾄少n次,但不多于m

案例1:

匹配test.swift文件中,description相关内容

grep "description.*\"$" test.swift
//或者
grep -E "description(.*)[\"]$" test.swift

案例2:

假定要分析的字符串是xfooxxxxxxfoo

模式.*foo(贪婪模式)由两部分

  • p1(.*)
  • p2(foo)

查看匹配结果,其中p1中的匹配⽅式使⽤默认⽅式(贪婪型)

  • 第⼀轮:匹配开始时,p1匹配所有字符xfooxxxxxx,匹配成功,但p2⽆匹配字符,本轮匹配失败
  • 第⼆轮:减少p1部分的匹配量,留出最后⼀个字符, 此时存在两个字符串,s1代表xfooxxxxxxfos2代表os1匹配p1, 但s2不匹配p2。本轮匹配失败
  • 第三轮,继续减少p1匹配量,留出两个字符, 字符串被分割成xfooxxxxxxfooo两部分。结果同上
  • 第四轮,再次减少p1匹配量,字符串分割成xfooxxxxxxfoo两个部分,这次p1/p2同时匹配。返回匹配成功

案例3:

模式.*?foo(勉强模式)最⼩匹配⽅式

  • p1(.*?)
  • p2(foo)

查看匹配结果,其中p1中的匹配⽅式使⽤勉强模式匹配

  • 第⼀轮:p1由于是0或任意次,⾸先匹配0次。所以直接⽤字符串去匹配p2,但p2⽆匹配字符,本轮匹配失败
  • 第⼆轮:增加p1部分的匹配量,匹配x。此时存在两个字符串,s1代表xs2代表fooxxxxxxfoos1匹配p1, 但s2不匹配p2。本轮匹配失败;继续上述匹配直到满⾜p2

案例4:

模式.*+foo(侵占模式)

  • p1(.*+)
  • p2(foo)

查看匹配结果,其中p1中的匹配⽅式使⽤侵占模式匹配

  • 匹配开始时读⼊所有字符串,和p1匹配成功,但没有剩余字符串去和p2匹配。匹配失败

简单地说,贪婪模式和侵占模式相⽐,贪婪模式会在只有部分匹配成功的条件下,依次从多到少减少匹配成功部分模式的匹配数量,将字符留给模式其他部分去匹配。⽽侵占模式则是占有所有能匹配成功部分,绝不留给其他部分使⽤

案例5:

使用(fooq|foo)*(qbarquux|bar)完全匹配的字符串是?

  • A、fooqbarquux
  • B、fooqbar
  • C、以上都选

仅选项B可以完全匹配,选项A只能匹配出fooqbar前半部分

案例6:

使用((a*)b)*\1\2完全匹配的字符串是?

  • A、aabababa
  • B、aabaabaabaabaa
  • C、以上都选

答案为选项C,选项AB都可以完全匹配

  • 如果分组不⽌⼀次匹配(例如,如果后⾯跟着重复运算符),则
    向后引⽤将匹配分组最后匹配的⼦字符串

案例7:

使用(one(x)|two(y))-and-(three\2|four\3)完全匹配的字符串是?

  • A、onex-and-threex
  • B、twoy-and-foury
  • C、onex-and-four
  • D、twoy-and-threey
  • E、twoy-and-threex

选项AB都可以完全匹配

  • 分组\2\3分别对应(x)(y),当(x)匹配失败,分组\2的位置存在,但分组报错
  • 当访问报错的分组,匹配将会中断

案例8:

t.swift文件中,删除description节点

使用description:(\W)(.*)将匹配的内容替换为空

结尾的渣男操作符.,除newlinenull匹配所有字符

案例9:

licensecredit的值,都改为https://www.baidu.com/

使用(license|credit):[\W](.)*将匹配的内容替换为$1: "https://www.baidu.com/",

  • $1表示分组\1(license|credit)
更⾼级的⽤法
零宽断⾔

断⾔:在指定位置应该满⾜⼀定的条件

当捕获组以开头时?=,表示该组将被⽤作零宽度正预测先⾏断⾔,仅当前⼀个模式与捕获组中的模式相匹配时才与前⼀个模式匹配。例如,A(?=B)A匹配,并且⻢上跟着B。可以匹配ABABBACB

Unicode

匹配特定类别的Unicode字符\p{ ... }

  • \p{L}所有字符,\p{Lu}所有⼩写字符,\p{N}
  • \P{}匹配不特定类别的Unicode字符
sed命令

sed命令:可以将数据进⾏替换、删除、新增、选取特定内容等功能,⽤作⼀整⾏字符处理

命令格式

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

选项

-e<script>或--expression=<script>:以选项中的指定的script来处理输入的文本文件;
-f<script文件>或--file=<script文件>:以选项中指定的script文件来处理输入的文本文件;
-h或--help:显示帮助;
-n或--quiet或——silent:仅显示script处理后的结果;
-V或--version:显示版本信息。

参数

文件:指定待处理的文本文件列表

sed命令

a\ # 在当前行下面插入文本。
i\ # 在当前行上面插入文本。
c\ # 把选定的行改为新的文本。
d # 删除,删除选择的行。
D # 删除模板块的第一行。
s # 替换指定字符
h # 拷贝模板块的内容到内存中的缓冲区。
H # 追加模板块的内容到内存中的缓冲区。
g # 获得内存缓冲区的内容,并替代当前模板块中的文本。
G # 获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l # 列表不能打印字符的清单。
n # 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N # 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p # 打印模板块的行。
P # (大写) 打印模板块的第一行。
q # 退出Sed。
b lable # 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
r file # 从file中读行。
t label # if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
T label # 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
w file # 写并追加模板块到file末尾。  
W file # 写并追加模板块的第一行到file末尾。  
! # 表示后面的命令对所有没有被选定的行发生作用。  
= # 打印当前行号码。  
# # 把注释扩展到下一个换行符以前。

sed替换标记

g # 表示行内全面替换。  
p # 表示打印行。  
w # 表示把行写入一个文件。  
x # 表示互换模板块中的文本和缓冲区中的文本。  
y # 表示把一个字符翻译为另外的字符(但是不用于正则表达式)
\1 # 子串匹配标记
& # 已匹配字符串标记

sed元字符集

^ # 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ # 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. # 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* # 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] # 匹配一个指定范围内的字符,如/[sS]ed/匹配sed和Sed。  
[^] # 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) # 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& # 保存搜索字符用来替换其他字符,如s/love/ **&** /,love这成 **love** 。
\< # 匹配单词的开始,如:/\<love/匹配包含以love开头的单词的行。
\> # 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} # 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} # 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} # 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。

参考文档:sed命令

awk命令

awk命令:⽐sed更精准,通常将⼀⾏在切割成相应的字段,再去处理

命令格式

awk [options] 'script' var=value file(s)
awk [options] -f scriptfile var=value file(s)

选项

-F fs fs指定输入分隔符,fs可以是字符串或正则表达式,如-F:
-v var=value 赋值一个用户定义变量,将外部变量传递给awk
-f scripfile 从脚本文件中读取awk命令
-m[fr] val 对val值设置内在限制,-mf选项限制分配给val的最大块数目;-mr选项限制记录的最大数目。这两个功能是Bell实验室版awk的扩展功能,在标准awk中不适用。

awk脚本是由模式和操作组成的

模式可以是以下任意一个:

  • /正则表达式/:使用通配符的扩展集
  • 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试
  • 模式匹配表达式:用运算符~(匹配)和!~(不匹配)
  • BEGIN语句块、pattern语句块、END语句块

操作由一个或多个命令、函数、表达式组成,之间由换行符或分号隔开,并位于大括号内,主要部分是:

  • 变量或数组赋值
  • 输出命令
  • 内置函数
  • 控制流语句

awk脚本基本结构

awk 'BEGIN{ print "start" } pattern{ commands } END{ print "end" }' file

一个awk脚本通常由:BEGIN语句块、能够使用模式匹配的通用语句块、END语句块三部分组成,这三个部分是可选的。任意一个部分都可以不出现在脚本中,脚本通常是被单引号双引号

awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
awk "BEGIN{ i=0 } { i++ } END{ print i }" filename

awk的工作原理

awk 'BEGIN{ commands } pattern{ commands } END{ commands }'
  • 第一步:执行BEGIN{ commands }语句块中的语句
  • 第二步:从文件或标准输入(stdin)读取一行,然后执行pattern{ commands }语句块,它逐行扫描文件,从第一行到最后一行重复这个过程,直到文件全部被读取完毕
  • 第三步:当读至输入流末尾时,执行END{ commands }语句块

案例1:

echo -e "A line 1\nA line 2" | awk 'BEGIN{ print "Start" } { print } END{ print "End" }'
Start
A line 1
A line 2
End
  • BEGIN语句块在awk开始从输入流中读取行之前被执行,这是一个可选的语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN语句块中
  • END语句块在awk从输入流中读取完所有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END语句块中完成,它也是一个可选语句块
  • pattern语句块中的通用命令是最重要的部分,它也是可选的。如果没有提供pattern语句块,则默认执行{ print },即打印每一个读取到的行,awk读取的每一行都会执行该语句块

案例2:

echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1,var2,var3; }' 
v1 v2 v3
  • 当使用不带参数的print时,它就打印当前行,当print的参数是以逗号进行分隔时,打印时则以空格作为定界符。在awkprint语句块中双引号是被当作拼接符使用

案例3:

双引号拼接使用

echo | awk '{ var1="v1"; var2="v2"; var3="v3"; print var1"="var2"="var3; }'
v1=v2=v3
  • { }类似一个循环体,会对文件中的每一行进行迭代,通常变量初始化语句(如:i=0)以及打印文件头部的语句放入BEGIN语句块中,将打印的结果等语句放在END语句块中

参考文档:awk命令

lldb使⽤正则对指定代码添加断点

对符合正则表达式的符号下断点

breakpoint set --func-regex=[regular-expression]

对指定库中的符合正则表达式的符号下断点

breakpoint set --func-regex=[regular-expression] --shlib=libfoo.dylib

通过对指定的正则表达式对⽂件内容设置断点

breakpoint set --source-pattern-regexp [regular-expression] --file [SourceFile]

案例

Block源码中,搜索blockcopy相关的代码

使用(.*)[B|b]lock(.*)[C|c]opy(.*)匹配相关代码

使用命令对符合正则的符号下断点

breakpoint set --func-regex=(.*)[B|b]lock(.*)[C|c]opy(.*)
  • 共设置1990处断点

使用br-r等缩写形式

br set -r (.*)[B|b]lock(.*)[C|c]opy(.*)
  • 使用长参数--func-regex,后面的值可以用等号或空格设置
  • 使用短参数-r,后面的值只能用空格设置

更简单的缩写:rb命令

rb (.*)[B|b]lock(.*)[C|c]opy(.*)

查看rb命令

help rb
-------------------------
'rb' is an abbreviation for 'breakpoint set -r %1'

指定在动态库libsystem_blocks.dylib中设置断点

rb (.*)[B|b]lock(.*)[C|c]opy(.*) --shlib=libsystem_blocks.dylib
  • 断点设置的范围缩小,共设置3处断点

使用-s缩写参数

rb (.*)[B|b]lock(.*)[C|c]opy(.*) -s libsystem_blocks.dylib

对指定⽂件内容设置断点

br set --source-pattern-regexp (.*)[B|b]lock(.*)[C|c]opy(.*) --file runtime.cpp

使用-p-f等缩写参数

br set -p (.*)[B|b]lock(.*)[C|c]opy(.*) -f runtime.cpp

自定义简写命令

使用command alias命令,为br set -p创建简写命令

command alias pb br set -p %1 -f %2
-------------------------
error: 'br' is not an existing command.

br命令已经是breakpoint的简写形式,这里必须对breakpoint命令进行设置

command alias pb breakpoint set -p %1 -f %2

设置成功后,可以直接使用简写命令

pb (.*)[B|b]lock(.*)[C|c]opy(.*) runtime.cpp

查看pb命令

help pb
-------------------------
'pb' is an abbreviation for 'breakpoint set -p %1 -f %2'

lldb中设置的简写命令,仅在本次调试中有效

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,711评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,079评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,194评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,089评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,197评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,306评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,338评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,119评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,541评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,846评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,014评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,694评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,322评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,026评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,257评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,863评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,895评论 2 351

推荐阅读更多精彩内容