【发布时间】:2013-11-30 09:04:36
【问题描述】:
如何限制查找和替换以替换项目,但如果紧接在它之前的字符是“A”、“B”或“C”或紧随其后的字符是“X”、“Y”,则不能,或“Z”。例如。给定这些输入行,如果要将“cat”替换为“pet”:
- “有一只猫。” → “这是一只宠物。”
- “有 Acat。”没有改变,因为之前找到了“A”。
- “有猫。”没有改变,因为“Y”是在后面找到的。
- “有 CcatX。”没有改变,因为“C”出现在前面,“X”出现在后面。
【问题讨论】:
如何限制查找和替换以替换项目,但如果紧接在它之前的字符是“A”、“B”或“C”或紧随其后的字符是“X”、“Y”,则不能,或“Z”。例如。给定这些输入行,如果要将“cat”替换为“pet”:
【问题讨论】:
这个 sed 应该适合你:
sed -r 's/(^|[^ABC])cat\>/\1pet/g; s/\<cat([^XYZ]|$)/pet\1/g' file
测试:
sed -r 's/(^|[^ABC])cat\>/\1pet/g; s/\<cat([^XYZ]|$)/pet\1/g' <<< 'cat is a cat is a cat'
pet is a pet is a pet
【讨论】:
cat is a cat is a cat测试。
pet is a pet is a pet
pet is a cat is a pet。反正我投了你一票。
这可能对你有用(GNU sed):
sed 's/\bcat\b/pet/g' file
或:
sed 's/\<cat\>/pet/g' file
或根据 cmets:
sed -r 's/(\b|[^ABC])cat(\b|[^XYZ])/\1pet\2/g' file
【讨论】:
"there are cats" 应该变成 "there are pets" 但这不会这样做。
假设您的文本位于名为text.txt 的文件中。这将起作用:
sed -i 's/\(.*[^ABC]\|^\)cat\([^XYZ].*\|$\)/\1pet\2/g' text.txt
发生了什么(来自tutorialspoint.com、man sed 和sed regex):
-i Edit files in place (makes backup if extension supplied)
s/???/???/ Or s/regexp/replacement/, Attempt to match regexp against the pattern space.
/ Field separator to 's'.
^ Match first character on line.
\( Start back reference.
. Match any character.
[^ABC] Do not match any charcter (^ = don't) in this list.
\| Matches regex1 or regexp2 (do not match ABC or match start of line).
\) End back reference.
cat Match cat
\1 The first back reference.
\2 The second back reference.
g Replace all matches, not just the first match.
【讨论】:
cat is a cat
使用perl 可能是一个更好的主意,因为它支持前瞻/后瞻:
perl -lape 's/(?<![ABC])cat(?![XYZ])/pet/' input
【讨论】: