jon*_*scb 12 sed perl regular-expression
我想使用sed
或perl
替换前面没有某个词的所有出现的词。
例如,我有一个包含电影情节的文本文件,我想用他们的名字替换所有出现的角色姓氏,但前提是他们的名字不紧跟在他们的姓氏之前。
示例文本可能如下所示:
John Smith and Jane Johnson talk about Smith's car.
Run Code Online (Sandbox Code Playgroud)
我希望它看起来像这样:
John Smith and Jane Johnson talk about John's car.
Run Code Online (Sandbox Code Playgroud)
如果我只是这样做sed 's/Smith/John/' file
,那么我会:
John John and Jane Johnson talk about John's car.
Run Code Online (Sandbox Code Playgroud)
姓氏之前的名字将始终相同。我不必处理John Smith
和Frank Smith
。我只需要一种方法来匹配Smith
它John
前面没有的。
使用正则表达式能够回顾的任何语言都会很容易。当然,Perl 是第一个:
perl -pe 's/(?<!John\W)Smith/John/g' <<< "John Smith and Jane Johnson talk about Smith's car."
Run Code Online (Sandbox Code Playgroud)
弱点是在“John”和“Smith”之间有一个以上的非单词字符。不幸的是,像+
for\W
这样的量词会引发“未实现可变长度后视”错误。
编辑..重新你的评论..这是一个新的脚本,它不关心(例如)威廉史密斯。它暂时混淆了保持为Smith(不变)的模式。
sed -r 's/\<(John) (Smith)\>/\1\x01x\2/g;
s/\<Smith\>/John/g; s/\x01x/ /g'
Run Code Online (Sandbox Code Playgroud)
如果你担心先生。 Mrs Mrs...那么这有效。
sed -r 's/\<(John|((M(r|rs|s))\.?)) (Smith)\>/\1\x01x\5/g
s/\<Smith\>/John/g; s/\x01x/ /g'
Run Code Online (Sandbox Code Playgroud)
您可以通过将他的名字添加到或列表来满足威廉的需求,例如。
sed -r 's/\<(William|John|...
这是原始脚本
sed -r 's/(^|[[:punct:]] |\<[a-z]+ )(Smith\>)/\1John/'
Run Code Online (Sandbox Code Playgroud)