-
2022-01-01 18:01:29
Word查找替换详细用法及通配符一览表
使用通配符
要查找“?”或者“*”,可输入“\?”和“\*”,\1\2\3依次匹配数对括号内容
查找(a)12(b) 替换\2XY\1 结果:bXYa([.0-9]@) [MG]B 匹配文件大小, 例1: 201 MB ,例2: 2.51 GB
<(e*r)> 匹配“ enter ”,不配“ entertain ”。主要有:
任意单个字符 ?
任意数字(单个)[0-9]或带小数点数字[.0-9]
任意英文字母 [a-zA-Z]或全小写[a-z]
指定范围外任意单个字符 [!x-z]
任意字符串 *
1个以上前一字符或表达式 @
n个以上前一字符或表达式 { n, }
制表符 ^t
不间断空格 ^s
段落标记 ^13
手动换行符 ^l or ^11
表达式 ( )
单词开头,结尾 < >
序 清除使用通配符复选框 查找 清除使用通配符复选框 替换栏 勾选使用通配符复选框 查找 勾选使用通配符复选框 替换栏 号 特殊字符 代码 特殊字符 代码or通配符 1 任意单个字符(只用于查找框) ^? 任意单个字符 ? 2 任意数字(单个)(只用于查找框) ^# ?段落符号 ^v 任意数字(单个) [0-9] ?段落符号 ^v 3 任意英文字母(只用于查找框) ^$ 任意英文字母 [a-zA-Z] 4 段落标记 ^p 段落标记? ^p 段落标记 ^13 段落标记? ^p 5 手动换行符 ^l 手动换行符↓ ^l 手动换行符 ^l or ^11 手动换行符↓ ^l 6 图形(只用于查找框) ^g or ^1 图形 ^g 7 1/4长划线 ^+ 1/4长划线( — ) ^q 1/4长划线 ^q 1/4长划线( — ) ^q 8 长划线 ^j 长划线 ^+ 长划线 ^+ 长划线 ^+ 9 短划线 ^q 短划线( – ) ^= 短划线 ^= 短划线( – ) ^= 10 制表符 ^t 制表符 ^t 制表符 ^t 制表符 ^t 11 脱字号 ^ 脱字号 ^^ 脱字号 ^^ 脱字号 12 分栏符 ^v 分栏符 ^n 分栏符 ^n or ^14 分栏符 ^n 13 分节符(只用于查找框) ^b 分节符/分页符 ^m 14 省略号 ^n 省略号 ^i 省略号 ^i 省略号 ^i 15 全角省略号 ^i 全角省略号 ^j 全角省略号 ^j 全角省略号 ^j 16 无宽非分隔符 ^z 无宽非分隔符 ^z 无宽非分隔符 ^z 无宽非分隔符 ^z 17 无宽可选分隔符 ^x 无宽可选分隔符 ^x 无宽可选分隔符 ^x 无宽可选分隔符 ^x 18 不间断空格 ^s 不间断空格 ^s 不间断空格 ^s 不间断空格 ^s 19 不间断连字符 ^~ 不间断连字符(-) ^~ 不间断连字符 ^~ 不间断连字符(-) ^~ 20 ?段落符号 ^% 表达式 ( ) ^^ 21 §分节符 ^ §分节符 ^% 单词开头 < §分节符 ^% 22 脚注标记(只用于查找框) ^f or ^2 单词结尾 > 23 可选连字符 ^- 可选连字符(_) ^- 任意字符串 * 可选连字符(_) ^- 24 空白区域 ^w 指定范围外任意单个字符 [!x-z] 25 手动分页符 ^m 手动分页符 ^m or ^12 指定范围内任意单个字符 [ - ] 手动分页符/分节符 ^m 26 尾注标记(只用于查找框) ^e 1个以上前一字符或表达式 @ 27 域(只用于查找框) ^d n 个前一字符或表达式 { n } 28 Unicode 字符 ^Unnnn n个以上前一字符或表达式 { n, } 29 全角空格 ^u8195 n 到m 个前一字符或表达式 { n,m } 30 半角空格 ^32 or ^u8194 所有小写英文字母 [a-z] 31 批注(只用于查找框) ^a or ^5 所有大写英文字母 [A-Z] 32 查找的内容 ^& 所有西文字符 [^1-^127] 查找的内容 ^& 33 剪贴板内容 ^c 所有中文汉字和中文标点 [!^1-^127] 剪贴板内容 ^c 34 所有中文汉字(CJK统一字符) [一-龥] or [一-﨩] 35 所有中文标点 [!一-龥^1-^127] 36 所有非数字字符 [!0-9] 注:要查找已被定义为通配符的字符,该字符前键入反斜杠 \ 。查找?、*、(、)、[ 、] 等的代码分别是\?、\*、\(、\)、\[、\] 。
Word查找栏代码,?通配符示例
特殊字符
代码or通配符
示例
任意单个字符(只用于查找框)
?
“蓝?公司”可找到“蓝天公司”和“蓝羚公司”
表达式
( )
“<(pre)*(ed)> ”可查找“presorted”和“prevented”
单词开头
<
“<(inter)”可找到“interesting”和“intercept”,而不会找“splintered”
单词结尾
>
“(in)>”可找到“in”和“within”,而不会找“interesting”
任意字符串(单个或多个字符)
*
“蓝*公司”可找到“蓝羚公司”和“蓝羚花木公司”
指定字符之一
[]
“[记纪]录”可找到“记录”和“纪录”
指定范围内任意单个字符
[ - ]
[r-t]ight可找到“right”“sight”,必须用升序来表示该范围
方括号内字符以外的任意单个字符
[!]
“m[!a]st”可找到“mist”和“most”,而不会找“mast”
指定范围外任意单个字符
[!x-z]
“t[!a-m]st”可找到“tock”和“tuck”,而不会找到“tack”或“tick”
1个以上前一字符或表达式
@
“lo@t”可找到“lot”和“loot”
n 个前一字符或表达式
{ n }
“fe{2}d”可找到“feed”,而不会找“fed”
n个以上前一字符或表达式
{ n, }
“fe{1,}d”可找到“fed”和“feed”
n 到m 个前一字符或表达式
{ n,m }
“10{1,3}”可找到“10”、“100”“1000”
使用“通配符”功能时需要注意的要点
1、要查找已被定义为通配符的字符,那么需要在该字符前输入反斜杠(\)。
例如:要查找“?”或者“*”,可输入“\?”和“\*”。
2、如果使用了通配符,在查找文字时会大小写敏感。如果希望查找大写和小写字母的任意组合,那么请使用方括号通配符。
例如:输入“[Hh]*[Tt]”可找到“heat”、“Hat” 或“HAT”,而用“H*t”就找不到“heat”。
3、使用通配符时,Word只查找整个单词。例如,搜索“e*r ”可找到“enter”,但不会找到“entertain”。如果要查找单词的所有形式,需要使用适当的通配符字符。
例如:输入“<(e*r)”可找到“enter”和“entertain”。
4、选中“使用通配符”复选框后,也可查找脚注和尾注、域、段落标记、分节符和人工分页符及空白区域。只要在“查找内容”框中键入替代代码即可。
5、如果包含可选连字符代码,Word 只会找到在指定位置带有可选连字符的文字。如果省略可选连字符代码,Word 将找到所有匹配的文字,包括带有可选连字符的文字。
6、如果要查找域,必需显示域代码。要在显示域代码和域结果之间切换,请单击该域,然后按 Shift+F9 组合键。要显示或隐藏文档中所有的域代码,请按 Alt+F9 组合键。
7、在查找图形时,Word 只查找嵌入图形,而不能查找浮动图形。在默认情况下,Word 会将导入的图形以嵌入图形的方式插入到文档中。
更多相关内容 -
快速模式匹配算法(KMP)的深入理解
2021-01-20 06:33:29这个功能主要来完成“查找”,“替换”和“全部替换”功能的,其实这就是典型的模式匹配的应用,即在文本文件中查找串。1.模式匹配模式匹配的模型大概是这样的:给定两个字符串变量S和P,其中S成为目标串,其中包含n... -
关于word的匹配模式中怎样开启非贪婪模式
2021-05-18 14:05:11 -
Lua模式匹配
2020-04-15 14:15:06与其他几种脚本语言不通,Lua语言既没有使用POSIX正则表达式,也没有使用Perl正则表达式来进行模式匹配。之所以这样做的主要原因在于大小问题:一个典型的POSIX正则表达式实现需要超过4000行代码,这比所有...
与其他几种脚本语言不通,Lua语言既没有使用POSIX正则表达式,也没有使用Perl正则表达式来进行模式匹配。之所以这样做的主要原因在于大小问题:一个典型的POSIX正则表达式实现需要超过4000行代码,这比所有Lua语言标准库总大小的一半还大。相比之下,Lua语言模式匹配的实现代码只有不到600行。尽管Lua语言的欧式匹配做不到完整POSIX实现的所有功能,但是Lua语言的模式匹配仍然非常强大,同时还具有一些与标准POSIX不同但又可与之媲美的功能。模式匹配的相关函数
字符串标准库提供了基于模式的4个函数。我们已经初步了解过函数find和gsub,其余两个函数分别是match和gmatch。
函数string.find
函数string.find用于在指定的目标字符串中搜索指定的模式。最简单的模式就是一个单词,它智慧匹配到这个单词本身。例如,模式’hello’会在目标自服装中所搜子串"hello"。函数string.find找到一个模式后,会返回两个值:匹配到模式开始位置的索引和结束位置的索引。如果没有找到任何匹配,则返回nil:
s = "hello world" i,j = string.find(s,"hello") print(i,j) -- 1 5 print(string.sub(s,i,j)) -- hello print(string.find(s,"world")) -- 7 11 i,j = string.find(s,"l") print(i,j) -- 3 3 print(string.find(s,"lll")) -- nil
匹配成功后,可以以函数find返回的结果为参数调用函数string.sub来获取目标字符串匹配相应模式的子串。对于简单的模式来说,这一般就是模式本身。
函数string.find具有两个可选参数。第3个参数是一个索引,用于说明从目标字符串的哪个位置开始搜索。第4个参数是一个布尔值,用于说明是否进行简单搜索。所谓简单所有就是忽略模式而在目标字符串中进行单纯的“查找子字符串”的动作:> string.find("a[word]","[") stdin:1:malformed pattern (missing ']') > string.find("a [word]","[",1,true) -- 3 3
由于’[‘在模式中具有特殊含义,因此第1个函数调用会报错。在第2个函数调用中,函数只是把’['当作简单字符串。请注意,如果没有第3个参数,是不能传入第4个可选参数的。
函数string.match
由于函数string.match也用于在一个字符串搜索模式,因此它与函数string.find非常相似。不过,函数string.match返回的是目标字符串中与模式相匹配的那部分子串,而非该模式所在的位置:
print(string.match("hello world","hello")) -- hello
对于诸如’hello’这样固定的模式,使用这个函数并没有什么意义。然而,当模式是变量时,这个函数的强大之处就显现出来了。例如:
date = "Today is 15/4/2020" d = string.match(date,"%d + /%d + /%d +") print(d) -- 15/4/2020
函数string.gmatch
函数string.gmatch返回一个函数,通过返回的函数可以遍历一个字符串中所有出现的指定模式。例如,以下示例可以找出字符串s中出现的所有单词:
s = "some string" words = {} for w in string.gmatch(s,"%a+") do words[#words + 1] = w end
模式
大多数模式匹配库都是用反斜杠作为转义符。然后,这种方式可能会导致一些不良的后果。对于Lua语言的解析器而言,模式仅仅是普通的字符串。模式与其他的字符串一样遵循相同的规则,并不会被特殊对待;只有模式匹配相关的函数才会把它们当做模式进行解析。由于反斜杠是Lua语言中的转义符,所以我们应该避免它传递给任何函数。模式本身就难以阅读,到处把“\”换成“\”就更加火上浇油了。
我们可以使用双括号把模式括起来构成的长字符串来解决这个问题。然而,长字符串的写法对于通常比较短的模式而言又往往显得冗长。此外,我们还会失去在模式内进行转义的能力。
Lua语言的解决方案更加简单:Lua语言中的模式使用百分号作为转义符。总体上,所有被转义的字母都具有某些特殊含义,而所有被转移的非字母则代表其本身。
我们首先来学习字符分类的模式。所谓字符分类,就是模式中能够与一个特定集合中的任意字符相匹配的一项。例如,分类%d匹配的是任意数字。因此,可以使用模式’%d%d/%d%/d%d%d%d’来匹配dd/mm/yyyy格式的日期:s = "Deadline is 15/04/2020, firm date = "%d%d/%d%d/%d%d%d%d" print(string.match(s,date)) -- 15/04/2020
下表列出了所有预置的字符串分类及其对应的含义:
. 任意字符
%a 字母
%c 控制字符
%d 数字
%g 除空格外的可打印字符
%l 小写字母
%p 标点符号
%s 空白字符
%u 大写字母
%w 字母和数字
%x 十六进制数字
这些类的大写形式表示类的补集。例如,
%A
代表任意非字母的字符:print((string.gsub("hello, up-down!","%A","."))) -- hello..up.down.
在输出函数gsub的返回结果时,我们使用了额外的括号来丢弃第二个结果,也就是特换发生的次数。
当在模式中使用时,还有一些被称为魔法字符的字符具有特殊含义。Lua语言的模式所使用的魔法字符包括:
()
.
%
+
-
*
?
[
]
^
$
正如我们之前已经看到的,百分号同样可以用于这些魔法字符的转义。因此,%?
匹配一个问号,%%
匹配一个百分号。我们不仅可以用百分号对魔法字符进行转义,还可以将其用于其他所有字母和数字外的字符。当不确定是否需要转义时,为了保险起见就可以使用转义符。
可以使用字符集来创建自定义的字符分类,只需要在方括号内将单个字符和字符分类组合起来即可。例如,字符集[%w_]
匹配所有以下画线结尾的字母和数字,[01]
匹配二进制数字,[%[%]]
匹配方括号。如果想要统计一段文本中元音的数量,可以使用如下的代码:_,nvow = string.gsub(text,"[AEIOUaeiou]","")
还可以在字符集中包含一段字符范围,做法是写出字符范围的第一个字符和最后一个字符并用横线将它们连接在一起。由于大多数常用的字符范围都被预先定义了,所以这个功能很少被使用。例如,
%d
相当于[0,9]
,%x
相当于[0-9a-fA-F]
。不过,如果需要查找一个八进制的数字,那么使用[0-7]
就比显示地枚举[01234567]
强多了。
在字符集前加一个补字符^就可以得到这个字符集对应的补集:模式[^\n]
则代表除换行符以外的其他字符。尽管如此,我们还是要记得对于简单的分类来说可以使用大写形式来获得对应的补集:$S
显然要比[^%s]
更简单。
还可以通过描述模式中重复和可选部分的修饰符来让模式更加有用。Lua语言中的模式提供了4中修饰符:
+
重复一次或多次
*
重复零次或多次
-
重复零次或多次(最小匹配)
?
可选(出现零次或一次)
修饰符 + 匹配原始字符串分类中的一个或多个字符,它总是获取与模式相匹配的最长序列。例如,模式’%a+'代表一个或多个字母:
print((string.gusb("one , and two; and three", "%a+","word"))) -- word, word word; word word
模式’%d+'匹配一个或多个数字
print(string.match("the number 1298 is event","%d+")) -- 1298
修饰符 * 类似于修饰符+,但是它还接受对应字符分类出现零次的情况。该修饰符一个典型的用法就是在模式的部分之间匹配可选的空格。例如,为了匹配像()或()这样的空括号对,就可以使用模式
'%(%s*%)'
,其中的'%s*'
匹配零个或多个空格。另一个示例是用模式'[_%a][_%w]*'
匹配Lua程序中的标识符:标识符是一个由字母或下画线开头,并紧跟零个或多个由下画线、字母或数字组成的序列。
修饰符-和修饰符 * 类似,也是用于匹配原始字符分类的零次或多次出现。不过,跟修饰符 * 总是匹配能匹配的最长序列不同,修饰符-只会匹配最短序列。虽然有时它们两者并没有什么区别,但大多数情况下这两者会导致截然不同的结果。例如,当试图用模式'[_%a][_%w]-'
查找标识符时,由于[_%w]-
总是匹配空序列,所以我们只会找到第一个字母。又如,假设我们想要删掉某C语言程序中的所有注释,通常会首先尝试使用'/%*.*%*/'
。然而,由于'.*
会尽可能长地匹配,因此程序中的第一个"/*"
只会与最后一个"*/"
相匹配:test = "int x; /* x */ int y; /* y * /" print((string.gsub(test,"/%*.*%*/", ""))) -- int x
相反,模式’.-'则只会匹配到找到的第一个"*/",这样就能得到期望的结果:
test = "int x; /* x */ int y; /* y * /" print((string.gsub(test,"/%*.-*%*/", ""))) -- int x; int y
最后一个修饰符?可用于匹配一个可选的字符。例如,假设我们想在一段文本中寻找一个证书,而这个证书可能包括一个可选的符号,那么就可以使用模式
[+-]?%d+
来完成这个需求,该模式可以匹配像“-12”、“23”和“+1009”这样的数字。其中字符分类[+-]
匹配加号或减号,而其后的问号则代表这个符号是可选的。
与其他系统不同的是,Lua语言中的修饰符只能作用于一个字符模式,而无法作用于一组分类。例如,我们不能写出匹配一个可选的单词的模式。通常,可以使用一些高级技巧来绕开这个限制。
以补字符^开头的模式表示从目标字符串开头开始匹配。类似地,以$结尾的模式表示匹配到目标字符串的结尾。我们可以同时使用这两个标记来限制匹配查找和锚定模式。例如,如下的代码可以用来检查字符串s是否以数字开头:if string.find(s,"^%d") then ...
如下的代码用来检查字符串是否为一个没有多余前缀字符和后缀字符的整数:
if string.find(s."^[+-]?%d+$") then ...
^和$字符只有位于模式的开头和结尾时才具有特殊含义;否则,它们仅仅就是与其身相匹配的普通字符。
模式%b
匹配成对的字符串,它的写法是%bxy
,其中x和y是任意两个不同的字符,x作为起始符而y作为结束字符。例如,模式%b()
匹配以左括号开始并以对应右括号结束的子串:s = "a (enclosed (in) parentheses line" print((string.gsub(s,"%b()","")) -- a line
通常,我们使用
%b()
、%b[]
、%b{}
或%b<>
等作为模式,但实际上可以用任意不同的字符作为分隔符。
最后,模式%f[char-set]
代表前置模式。该模式只有在后一个字符位于char-set内而前一个字符不在时匹配一个空字符串:s = "the anthem is then theme" print((string.gsub(s,"%f[%w]the%f[%W]","one"))) -- one anthem is one theme
模式
%f[%w]
匹配位于一个非字母或数字的字符和一个字母或数字的字符之间的前置,而模式%f[%W]
则匹配一个字母或数字的字符和一个非字母或数字的字符之间的前置。因此,指定的模式只会匹配完整的字符串"the"。请注意,即使字符集只有一个分类,也必须把它用括号括起来。
前置模式把目标字符串中第一个字符前和最后一个字符后的位置当成空字符。在前例中,第一个"the"在不属于集合[%W]
的空字符和属于集合[%W]
的t之间匹配了一个前置。捕获
捕获机制允许根据一个模式从目标字符串中抽出与该模式匹配的内容来用于后续用途,可以通过把模式中需要捕获的部分放到一对圆括号内来指定捕获。
对于具有捕获的模式,函数string.match会将所有捕获到的值作为单独的结果返回;换句话说,该函数将字符串切分成多个被捕获的部分:pair = "name = Anna" key,value = string.match(pair, "(%a+)%s*=%s*(%a+)") print(key,value) -- name Anna
模式
%a+
表示一个非空的字母序列,模式%s*
表示一个可能为空的空白序列。因此,上例中的这个模式表示一个字母序列、紧跟着空白序列、一个等号、空白序列以及另一个字母序列。模式中的两个字母系列被分别放在圆括号中,因此在匹配时就能捕获到它们。下面是一个类似的示例:date = "Today is 15/4/2020" d,m,y = string.match(date,"(%d+)/(%d+)/(%d+)") print(d,m,y) -- 15 4 2020
在这个示例中,使用了3个捕获,每个捕获对应一个数字序列。
在模式中,形如%n
的分类,表示匹配第n个捕获的副本。举一个典型的例子,假设想在一个字符串中寻找一个由单引号或双引号括起来的子串。那么可能会尝试使用模式’[" '].-[" ‘]’,它表示一个引号后面跟任意内容及另外一个引号;但是,这种模式在处理像"it’s all right"这样的字符串时会有问题。要解决这个问题,可以捕获第一个引号然后用它来指明第二个引号:s = [[then he said:"it's all right"!]] q, quotedPart = string.match(s,"([\"'])(.-)%1") print(quotedPart) -- it's all right print(q) -- "
第1个捕获是引号本身,第2个捕获是引号中的内容。
下例是一个类似的示例,用于匹配Lua语言中的长字符串的模式:%[(=*)%[(.-)%]%1%]
它所匹配的内容依次是:一个左方括号、零个或多个等号、另一个左方括号、任意内容(字符串的内容)、一个右方括号、相同数量的等号及另一个右方括号:
p = "%[(=*)%[(.-)%]%1%]" s = "a = [ = [[[ something ]] ] == ] ] =];print(a)" print(string.match(s,p)) -- [[something]] ] == ]
第1个捕获是等号序列,第2个捕获是字符串内容。
被捕获对象的第3个用途是在函数gsub的替代字符串中。像模式一样,替代字符串同样可以包括像"%n"一样的字符分类,当发生替换时会被替换为相应的捕获。特别地,“%0”意味着整个匹配,并且替换字符串中的百分号必须被转义为“%%”。下面这个示例会重复字符串中的每个字母,并且在每个被重复的字母之间插入一个减号:print((string.gsub("hello Lua!","%a","%0-%0"))) -- h-he-el-ll-lo-o L-Lu-ua-a!
下例交换了相邻的字符:
print((string.gsub("hello Lua!","(.)(.)","%2%1"))) -- ehll ouLa
替换
正如我们此前已经看到的,函数string.gsub的第3个参数不仅可以是字符串,还可以是一个函数或表。当第3个参数是一个函数时,函数string.gsub会在每次找到匹配时调用该函数,参数是捕获到的内容而返回值则被作为替换字符串。当第3个参数是一个表时,函数string.gsub会把第一个捕获到的内容作为建,然后将表中对应该键的值作为替换字符串。如果函数的返回值为nil或表中不包含这个键或表中键的对应值为nil,那么函数gsub不改变这个匹配。
先举一个例子,下述函数用于变量展开,它会把字符串中所有出现的$varname替换为全局变量varname的值:function expand(s) return (string.gsub(s,"$(%w+)",_G)) end name = "Lua";status = "great" print(expand("$name is %status, isn't it?")) -- Lua is great ,isn't it?
(_G是预先定义的包括所有全局变量的表)对于每个与
$(%w_)
匹配到的地方,函数gsub都会在全局表_G中查找捕获到的名字,并用找到的结果替换字符串中相匹配的部分;如果表中没有对应的键,则不进行替换:print(expand("$othername is $status, isn't it?")) -- $othername is great,isn't it?
如果不确定是否制定变量具有字符串值,那么可以对它们的值调用函数tostring。在这种情况下,可以用一个函数来返回要替换的值:
function expand(s) return (string.gsub(s,"$(%w+)",function(n) return tostring(_G[n]) end)) end print(expand("print = $print; a = $a")) -- print = function:0x8050; a = nil
在函数expand中,对于所有匹配
$(%w+)
的地方,函数gsub都会调用给定的函数,传入捕获到的名字作为参数,并使用返回字符串替换匹配到的内容。URL编码
我们的下一个示例中将用到URL编码,也就是HTTP所使用的在URL中传递参数的编码方式。这种编码方式会将特殊字符编码为"%xx"的形式,其中xx是对应字符的十六进制。此外,URL编码还会将空格转换为加号。例如,字符串
a + b = c
的URL编码为a%2Bb+%3D+c
。最后,URL编码会将对参数名及其值用等号连接起来,然后将每对name = value用&连接起来。例如,值
name = "al"
;query = "a+b = c"
;q = "yes or no"
对应的URL编码为name=al&query=a%2Bb+%3D+c&q=yes+or+no
。
现在,假设要将这个URL解码并将其中的键值对保存到一个表内,以相应的键作为索引,那么可以使用一下函数完成基本的解码:function unescape(s) s = string.gsub(s,"+"," ") s = string.gsub(s,"%%(%x%x)",function(h) return sting.char(tonumber(h,16)) end) return s end print(unescape("a%2Bb+%3D+c")) -- a + b = c
第一个gsub函数将字符串中的所有加号替换为空格,第二个gsub函数则匹配所有以百分号开头的两位十六进制数,并对每处匹配调用一个匿名函数。这个匿名函数会将十六进制转换成一个数字并返回其对应的字符。
可以使用函数gmatch来对键值对name = value进行解码。由于键名和值都不能包含&或=,所以可以使用模式[^&=]+
来匹配它们:cgi = {} function decode(s) for name, value in string.gmatch(s,"([^&=]+)=([^&=]+)") do neme = unescape(name) value = unescape(value) cgi[name] = value end end
调用函数gmatch会匹配所有格式为name=value的键值对。对于每组键值对,迭代器会返回对应的捕获,捕获到的内容也就是name和value的值。循环体内只是简单地对两个字符串调用函数unescape,然后将结果保存到表cgi中。
对应的编码函数也很容易编写。先写一个escape函数,用它将所有的特殊字符编码为百分号紧跟对应的十六进制形式,然后把空格替换成加号:function escape(s) s - string.gsub(s,"[&=+%%%c]",function(c) return string.format("%%%02X",string.byte(c)) end) s = string.gsub(s," ","+") return s end
encode函数会遍历整个待编码的表,然后构造出最终的字符串:
function encode(t) local b = {} for k,v in pairs(t) do b[#b + 1] = (escape(k) .. "=" .. escape(v)) end -- 将b中所有元素连接在一起,使用"&"分隔 return table.concat(b,"&") end t = {name = "al",query = "a+b=c" , q = "yes or no"} print(encode(t)) -- q = yes+or+no&query=a%2Bb+%3D+c&name=al
制表符展开
在Lua语言中,像
()
这样的空白捕获具有特殊含义。该模式并不代表捕获空内容,而是捕获模式在目标字符串中的位置:print(strig.match("hello","()ll()")) -- 3 5
另一个关于位置捕获的良好示例是在字符串中进行制表符展开:
function expandTabs(s,tab) tab = tab or 8 -- 制表符的"大小"(默认是8) local corr = 0 -- 修正量 s = string.gsub(s,"()\t",function(p) local sp = tab - (p - 1 + corr)%tab) corr = corr - 1 + sp return string.rep("",sp) end) return s end
函数gsub会匹配字符串中所有的制表符并捕获它们的位置。对于每个制表符,匿名函数会根据其所在位置计算出需要多少个空格才能恰好凑够一列(整数个tab):该函数先将位置减去1以从0开始计数,然后加上corr凑整之前的指标符(每一个被展开的指标符都会影响后续制表符的位置)。之后,该函数更新下一个制表符的修正量:为正在被去掉的制表符减1,再加上要增加的空格数sp。最后,这个函数返回由替代制表符的合适数量的空格组成的字符串。
为了完整起见,让我们再看下如何实现逆向操作,即将空格转换为制表符。第一种方法是通过空捕获来对位置进行操作,但还有一种更简单的方法:即在字符串中每隔8个字符插入一个标记,然后将前面有空格的标记替换为制表符。function unexpandTabs(s,tab) tab = tab or 8 s = expandTabs(s,tab) local pat = string.rep(".",tab) -- 辅助模式 s = string.gsub(s,pat,"%0\1") -- 在每8个字符后添加一个标记\1 s = string.gsub(s,"+\1","\t") -- 将所有以此标记结尾的空格序列都替换为制表符\t s = string.gsub(s,"\1","") -- 将剩下的标记\1删除 return s end
这个函数首先对字符串进行了制表符展开以移除其中所有的制表符,然后构造出一个用于匹配所有8个字符序列的辅助模式,再利用这个模式在每8个字符后添加一个标记。接着,它将所有以此标记结尾的空格序列都替换为制表符。最后,将剩下的标记删除。
诀窍
模式匹配是进行字符串处理的强大工具之一。虽然通过多次调用函数string.gsub就可以完成许多复杂的操作,但是还是应该谨慎地使用函数。
模式匹配替代不了传统的解析器。对于那些用后即弃的程序来说,我们确实可以在源代码中做一些有用的操作,但却很难构建出高质量的产品。
通常,在Lua程序中使用模式匹配时的效率是足够高的,但仍然需要注意,应该永远使用尽可能的精确的模式,不精确的模式会比精确的模式慢很多。一个极端的例子是模式(.-)%$
,它用于获取字符串中第一个 字 符 前 的 所 有 内 容 。 如 果 目 标 字 符 串 中 有 字符前的所有内容。如果目标字符串中有 字符前的所有内容。如果目标字符串中有符号,那么这个模式工作很正常;但是,如果字符串中没有 符 号 , 那 么 匹 配 算 法 就 会 受 限 从 字 符 串 起 始 位 置 开 始 匹 配 , 直 至 为 了 搜 索 符号,那么匹配算法就会受限从字符串起始位置开始匹配,直至为了搜索 符号,那么匹配算法就会受限从字符串起始位置开始匹配,直至为了搜索符号而遍历完整字符串。当到达字符串结尾时,这次从字符串起始位置开始的模式匹配就失败了。之后,模式匹配算法又从字符串的第二个位置开始第二次搜索,结果仍然是无法匹配这个模式。这个匹配过程会在字符串的每个位置上进行一次,从而导致O(n2)的时间复杂度。
此外,还要留心空模式,也就是那些匹配空字符串的模式。例如,如果试图使用模式%a*
来匹配名字,那么 就会发现到处都是名字:i,j = string.find(";$% **#$hello13","%a*") print(i,j) -- 1 0
在这个示例汇中,函数string.find在字符串的开始位置正确地找到一个空的字母序列。
在模式的结束处使用修饰符-是没有意义的,因为这样只会匹配到空字符串。该修饰符总是需要在其后跟上其他的东西来限制扩展的范围。同样,含有".*"的模式也非常容易出错,这主要是因为这种模式可能会匹配到超出我们预期范围的内容。
有时,用Lua语言来构造一个模式也很有用。我们已经在将空格转换为制表符的程序中使用过这个技巧。接下来再看另外一个示例,考虑如何找出一个文本中较长的行(比如超出70个字符的行)。较长的行就是一个具有70个或更多字符的序列,其中每个字符都不为换行符,因而可以使用字符分类[^\n]
来匹配除换行符以外的其他单个字符。这样,就能够通过把这个匹配单个字符的模式重复70次来匹配较长的行。除了手写以外,还可以使用函数string.rep来创建这个模式:pattern = string.ret("[^\n]",70 .. "+")
再举一个例子,假设要进行大小写无关的查找。一种方法就是将模式中的所有字母x用
[xX]
替换,即同时包含原字母大小写形式的字符分类。我们可以使用如下函数来自动地完成这种替换:function oncase(s) s = string.gsub(s,"%a",function(c) return "[" .. string.lower(c) .. string.upper(c).."]" end) return s end print(nocase("Hi there!")) -- [hH][iI][tT][hH][eE][rR][eE]!
有时,我们可能需要将所有出现的s1替换为s2,而不管其中是否包含魔法字符。如果字符串s1和s2是常量,那么可以在编写字符串时对魔法字符进行合理的转义;但如果字符串是一个变量,那么就需要用另一个gsub函数来进行转义:
s1 = string.gsub(s1,"(%W)","%%%1") s2 = string.gsub(s2,"%%","%%%%")
在进行字符串搜索时,我们对所有字母和数字外的字符进行了转义(即大写的W)。而在替换字符串中,我们只对百分号进行了转义。
模式匹配的另一个有用的技巧就是,在进行实际工作前对目标字符串进行预处理。假设想把一个字符串中所有被双引号(")引起来的内容改为大写,但又允许内容中包含转义的引号("""):follows a typical string:"This is \"great\"!".
处理这种情况的方法之一就是先对文本进行预处理,将所有可能导致歧义的内容编码成别的内容。例如,可以讲
"\""
编码成"\1"
。不过,如果原文中本身就含有"\1"
,那么就会遇到问题。另一种可以避免这个问题的简单做法是将所有"\x"
编码为"\ddd"
,其中ddd为字符x的十六进制表示形式:function code(s) return (string.gsub(s,"\\(.)",function(x) return string.format("\\%03d",string.byte(x)) end)) end
这样,由于原字符串中所有的
"\ddd"
都进行了编码,所以编码后字符串中的"\ddd"
序列一定都是编码造成的。这样,解码也就很简单了:function decode(s) return (string.gsub(s,"\\(%d%d%d)",function(d) return "\\" .. string.char(tonumber(d)) end)) end
现在我们就可以完成把一个字符串中被双引号(")引起来的内容改为大写的需求。由于编码后的字符串中不包含任何转义的引号
("\"")
,所以就可以直接使用"._"
来查找位于一对引号中的内容:s = [[follows a typical string:"This is \"great\"!".]] s = code(s) s = string.gsub(s,'".-"',string.upper) s = decode(s) print(s) -- follows a typical string:"THIS IS \"GREAT\"!".
或者写成:
print(decode(string.gsub(code(s),'".-"',string.upper)))
是否能够将模式匹配函数用于UTF-8字符串取决于模式本身。由于UTF-8的主要特征之一就是任意字符的编码不会出现在别的字符的编码中,因此文本类的模式一般可以正常工作。字符分类和字符集只对ASCII字符有效。例如,可以对UTF-8字字符串使用模式’%s’,但它只能匹配ASCII空格,而不能匹配诸如HTML空格或蒙古文元音分隔符等其他的Uicode空格。
恰当的模式能够为处理Unicode带来额外的能力。一个优秀的例子是预定义模式utf8.charpattern,该模式只精确地匹配一个UTF-8字符。utf8标准库中就是按照下面的方法定义这个模式的:utf8.charpattern = [\0-\x7F\xC2-\xF4][\x80-\xBF]*
该模式的第1部分匹配ASCII字符或多字节序列的其实字节。第2部分则匹配零个或多个后续的自己。
-
Shell 命令中的特殊替换、模式匹配替换、字符串提取和替换
2018-05-30 21:16:37形式说明${var}变量本来的值${var:-word}如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。${var:=word}如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。$...形式 说明 ${var} 变量本来的值 ${var:-word} 如果变量 var 为空或已被删除(unset),那么返回 word,但不改变 var 的值。 ${var:=word} 如果变量 var 为空或已被删除(unset),那么返回 word,并将 var 的值设置为 word。 ${var:?message} 如果变量 var 为空或已被删除(unset),那么将消息 message 送到标准错误输出,可以用来检测变量 var 是否可以被正常赋值。
若此替换出现在Shell脚本中,那么脚本将停止运行。${var:+word} 如果变量 var 被定义,那么返回 word,但不改变 var 的值。 特殊替换——${var:-string},${var:+string},${var:=string},${var:?string}
①${var:-string}和${var:=string}:若变量var为空,则用在命令行中用string来替换${var:-string},否则变量var不为空时,则用变量var的值来替换${var:-string};不同之处是${var:=string}常用于判断var是否赋值,没有的话则给var赋上一个默认值。
② ${var:+string}:替换规则和上面的相反,即只有当var不是空的时候才替换成string,若var为空时则不替换或者说是替换成变量 var的值,即空值。(因为变量var此时为空,所以这两种说法是等价的)
③${var:?string}:替换规则为:若变量var不为空,则用变量var的值来替换${var:?string};若变量var为空,则把string输出到标准错误中,并从脚本中退出。我们可利用此特性来检查是否设置了变量的值。
注意:在上面这五种替换结构中string不一定是常值的,可用另外一个变量的值或是一种命令的输出。
模式匹配替换——${var%pattern},${var%%pattern},${var#pattern},${var##pattern}
# 是去掉左边(在键盘上#在$之左边);% 是去掉右边(在键盘上%在$之右边);#和%中的单一符号是最小匹配,两个相同符号是最大匹配。
第一种模式:${variable%pattern}。shell在variable中查找,看它是否一给的模式pattern结尾,如果是,把variable去掉右边最短的匹配模式
第二种模式: ${variable%%pattern},这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,把variable中去掉右边最长的匹配模式
第三种模式:${variable#pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern开始,如果是,把variable中去掉左边最短的匹配模式
第四种模式: ${variable##pattern} 这种模式时,shell在variable中查找,看它是否一给的模式pattern结尾,如果是,把variable中去掉左边最长的匹配模式
这四种模式中都不会改变variable的值,其中,只有在pattern中使用了*匹配符号时,%和%%,#和##才有区别。结构中的pattern支持通配符,*表示零个或多个任意字符,?表示仅与一个任意字符匹配,[...]表示匹配中括号里面的字符,[!...]表示不匹配中括号里面的字符。
- # var=testcase
- # echo $var
- testcase
- # echo ${var%s*e}
- testca
- # echo $var
- testcase
- # echo ${var%%s*e}
- te
- # echo ${var#?e}
- stcase
- # echo ${var##?e}
- stcase
- # echo ${var##*e}
- # echo ${var##*s}
- e
- # echo ${var##test}
- case
第一种模式:${var:num},shell在var中提取第num个字符到末尾的所有字符。若num为正数,从左边0处开始;若num为负数,从右边开始提取字串,但必须使用在冒号后面加空格或一个数字或整个num加上括号,如${var: -2}、${var:1-3}或${var:(-2)}。
第二种模式:${var:num1:num2},num1是位置,num2是长度。表示从$var字符串的第$num1个位置开始提取长度为$num2的子串。不能为负数。
第三种模式:${var/pattern/pattern}表示将var字符串的第一个匹配的pattern替换为另一个pattern。
第四种模式:${var//pattern/pattern}表示将var字符串中的所有能匹配的pattern替换为另一个pattern。
- [root@centos ~]# var=/home/centos
- [root@centos ~]# echo $var
- /home/centos
- [root@centos ~]# echo ${var:5}
- /centos
- [root@centos ~]# echo ${var: -6}
- centos
- [root@centos ~]# echo ${var:(-6)}
- centos
- [root@centos ~]# echo ${var:1:4}
- home
- [root@centos ~]# echo ${var/o/h}
- /hhme/centos
- [root@centos ~]# echo ${var//o/h}
- /hhme/cenths
-
Mathematica入门(二)原则2:模式匹配和规则替代
2020-05-24 19:08:46第二条原则:模式匹配和规则替代 另一条基本原则是所谓模式匹配。它是将规则与表达式进行匹配的一个系统。离开这个系统,Mathematica 将无法知道什么时候使用哪一条规则。给系统是按照语法而非语义在表达式间做... -
Word2016查找和替换通配符(完全版)
2020-04-02 16:54:00word查找/替换中支持的所有通配符的具体含义、使用方法和注意事项。 -
word中的正则表达式匹配
2019-04-01 22:25:12()用英文括号括起来的是一个表达式, 表达式内部匹配到的结果可以用 \1 其中1代表是第一个表达式,第二个表达式内容表示匹配0 9 , - 这几个字符的任意组合(避免某些括号中是别的东西)。 替换为输入: [/2] ... -
sed正则表达式匹配批量替换文件中的内容
2020-12-18 14:17:42处理时,把当前处理的行存储在临时缓冲区中,称为『模式空间』(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并... -
Word中使用正则表达式进行查找和替换(高效进行文字处理)
2018-12-05 14:12:05对我们来说,正则表达式指的是您可以用来查找和替换文本模式的文本字符和通配符组合。文本字符指的是必须存在于目标文本字符串中的文本。通配符指的是目标字符串中可能各不相同的文本。 试一试! 本节中的步骤... -
python替换word中的关键文字(使用通配符)
2020-12-06 10:10:10本文以替换为例,讲解一下如何使用Python在word中使用“通配符模式”(类似于正则表达式)替换文本内容。#!/usr/bin/env python# -*- coding:utf-8 -*-import osimport win32comfrom win32com.client import Dis... -
python实现替换word中的关键文字(使用通配符)
2021-01-12 21:25:24本文以替换为例,讲解一下如何使用Python在word中使用“通配符模式”(类似于正则表达式)替换文本内容。#!/usr/bin/env python# -*- coding:utf-8 -*-import osimport win32comfrom win32com.client import Dis... -
word中使用正则表达式进行查找和替换
2020-05-13 09:45:57请记住,始终使用**“查找和替换”**对话框来运行您的正则表达式。同时请记住,如果表达式没有按预期工作,你始终可以按下 CTRL + Z 来撤销您的更改,然后尝试其他表达式。 转置姓名 启动 Word,然后打开一个新的... -
Python替换字符串的正则匹配re.sub正确用法 - 米扑博客
2021-03-06 14:59:19re.sub 介绍re是Regular Expression的所写,表示正则表达式,sub是substitute的所写,表示替换的意思;re.sub是个正则表达式方面的函数,用来实现通过正则表达式,实现比普通字符串的replace更加强大的替换功能;re.... -
模式匹配函数
2018-01-30 15:00:29模式匹配函数 在string库中功能最强大的函数是: string.find(字符串查找) string.gsub(全局字符串替换) string.gfind(全局字符串查找) string.gmatch(返回查找到字符串的迭代器) 这些函数都是... -
VBA--word模板标签替换操作
2014-07-31 00:28:16最近项目中有个需求,就是用word生成word,把一份标签对组成的word源材料,放到word模板中。所以就想到用vba来做,可是之前就没有接触过这些啊,连个word排版用的都不怎么好,于是就到下载频道搜索关键词vba。从搜索... -
SHELL变量和变量替换
2021-05-16 04:26:12(6) ${#value} 变量的字符个数 (7) ${value#pattern} ${value##pattern} 去掉value中与pattern相匹配的部分,条件是value的开头与pattern相匹配 #与##的区别在于一个是最短匹配模式,一个是最长匹配模式.... -
Lua中模式匹配
2016-03-25 01:45:21Preface本篇主要讲的是Lua中的模式匹配,大多数资料没有讲得特别详细~这里就将《Lua程序设计》中的内容搬下来。 参考: (1) Lua官方的参考文档 (2) Lua字符串处理模式匹配可以用不同的匹配模式与任意字符串相... -
Python库FlashText——比正则表达式快得多的匹配和替换库
2020-12-14 16:59:51`FlashText` 可用于匹配或替换句子中的关键词。使用Aho-Corasick自动机算法和Trie字典树。比编译后的正则表达式快28倍,而且是纯Python实现。 -
lua string模式匹配
2017-04-25 20:25:47模式匹配函数 在string库中功能最强大的函数是: string.find(字符串查找) string.gsub(全局字符串替换) string.gfind(全局字符串查找) string.gmatch(返回查找到字符串的迭代器) -
lua之字符串模式匹配
2017-09-27 17:48:15在string库中功能最强大的函数是: 复制代码代码如下: string.find(字符串查找) ...这些函数都是基于模式匹配的。与其他脚本语言不同的是,Lua并不使用POSIX规范的正则表达式[4](也写作regexp)来进 -
Lua 的模式匹配
2015-09-06 13:56:46Lua 的模式匹配不使用Posix规范的正则表达式(也写做regexp)来进行模式匹配。主要的原因出于程序大小方面的考虑:实现一个典型的符合POSIX标准的regexp大概需要4000行代码,这比整个Lua标准库加在一起都大。权衡之... -
Python 替换字符串的正则匹配 re.sub 正确用法
2021-03-17 10:24:46re.sub 介绍re是Regular Expression的所写,表示正则表达式,sub是substitute的所写,表示替换的意思;re.sub是个正则表达式方面的函数,用来实现通过正则表达式,实现比普通字符串的replace更加强大的替换功能;re.... -
模式匹配运算符–Shell
2015-07-17 14:57:11${Variable#pattern}:如果模式匹配于变量值的开头处,则删除匹配的最短部分,并且返回剩下的部分 例子: [fire]$ echo ${Var#*/} [fire]$ home/firefox/MyProgram/fire.login.name [fire]$ echo ${Var#/* -
Qt:QRegExp类使用正则表达式提供模式匹配
2018-12-08 17:11:08QRegExp也可以用于更简单的通配符模式,类似于命令shell中的功能。 可以使用setPatternSyntax()更改QRegExp使用的语法规则。 特别是,模式语法可以设置为QRegExp :: FixedString,这意味着要... -
模式匹配和文本处理
2017-11-16 14:44:14模式匹配和文本处理 字符串的处理主要包括寻找字符中的模式(模式匹配),以及通过称为正则表达式的特殊语言来执行 正则表达式: 正则表达式是一种用于描述字符串格式的语言,它提供了对应于重复字符、替换字符... -
VBA之正则表达式(23)-- 替换指定位置字符
2021-01-29 02:51:21实例需求: 待处理字符重:`5*s+s[面积s=222m2]+s*5[套s=333m2s]+s+s/s^2` 处理规则:将保留中括号中的字符,将其他部分字符中的s替换数字3 结果为:`5*3+3[面积s=222m2]+3*5[套s=333m2s]+3+3/3^2` -
快速模式匹配算法
2017-07-11 10:55:30这个功能主要来完成“查找”,“替换”和“全部替换”功能的,其实这就是典型的模式匹配的应用,即在文本文件中查找串。1.模式匹配 模式匹配的模型大概是这样的:给定两个字符串变量S和P,其中S成为目标串,其中包含...