我看过这个例子:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
遵循以下语法:${variable//pattern/replacement}
不幸的是,模式字段似乎不支持完整的正则表达式语法(如果我使用。或者\s,例如,它试图匹配文字字符)。
我如何使用完整的正则表达式语法搜索/替换字符串?
我看过这个例子:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
遵循以下语法:${variable//pattern/replacement}
不幸的是,模式字段似乎不支持完整的正则表达式语法(如果我使用。或者\s,例如,它试图匹配文字字符)。
我如何使用完整的正则表达式语法搜索/替换字符串?
当前回答
如果您正在重复调用并且关心性能,这个测试显示BASH方法比分支到sed和可能的任何其他外部进程快15倍。
hello=123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X
P1=$(date +%s)
for i in {1..10000}
do
echo $hello | sed s/X//g > /dev/null
done
P2=$(date +%s)
echo $[$P2-$P1]
for i in {1..10000}
do
echo ${hello//X/} > /dev/null
done
P3=$(date +%s)
echo $[$P3-$P2]
其他回答
使用sed:
MYVAR=ho02123ware38384you443d34o3434ingtod38384day
echo "$MYVAR" | sed -e 's/[a-zA-Z]/X/g' -e 's/[0-9]/N/g'
# prints XXNNNNNXXXXNNNNNXXXNNNXNNXNNNNXXXXXXNNNNNXXX
注意,后面的-e是按顺序处理的。此外,表达式的g标志将匹配输入中出现的所有情况。
你也可以使用这个方法选择你最喜欢的工具,例如perl, awk,例如:
echo "$MYVAR" | perl -pe 's/[a-zA-Z]/X/g and s/[0-9]/N/g'
这可以让你做出更有创意的搭配……例如,在上面的片段中,除非在第一个表达式上有匹配,否则不会使用数字替换(由于延迟和求值)。当然,您有Perl的完整语言支持来执行您的命令……
这个例子在输入hello ugly世界中搜索正则表达式bad|ugly并将其替换为nice
#!/bin/bash
# THIS FUNCTION NEEDS THREE PARAMETERS
# arg1 = input Example: hello ugly world
# arg2 = search regex Example: bad|ugly
# arg3 = replace Example: nice
function regex_replace()
{
# $1 = hello ugly world
# $2 = bad|ugly
# $3 = nice
# REGEX
re="(.*?)($2)(.*)"
if [[ $1 =~ $re ]]; then
# if there is a match
# ${BASH_REMATCH[0]} = hello ugly world
# ${BASH_REMATCH[1]} = hello
# ${BASH_REMATCH[2]} = ugly
# ${BASH_REMATCH[3]} = world
# hello + nice + world
echo ${BASH_REMATCH[1]}$3${BASH_REMATCH[3]}
else
# if no match return original input hello ugly world
echo "$1"
fi
}
# prints 'hello nice world'
regex_replace 'hello ugly world' 'bad|ugly' 'nice'
# to save output to a variable
x=$(regex_replace 'hello ugly world' 'bad|ugly' 'nice')
echo "output of replacement is: $x"
exit
如果您正在重复调用并且关心性能,这个测试显示BASH方法比分支到sed和可能的任何其他外部进程快15倍。
hello=123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X123456789X
P1=$(date +%s)
for i in {1..10000}
do
echo $hello | sed s/X//g > /dev/null
done
P2=$(date +%s)
echo $[$P2-$P1]
for i in {1..10000}
do
echo ${hello//X/} > /dev/null
done
P3=$(date +%s)
echo $[$P3-$P2]
设置var
hello=ho02123ware38384you443d34o3434ingtod38384day
然后,在var上用regex替换echo
echo ${hello//[[:digit:]]/}
这将打印:
howareyoudoingtodday
额外-如果你想要相反的(获得数字字符)
echo ${hello//[![:digit:]]/}
这将打印:
021233838444334343438384
你可以使用python。这样做效率不高,但可以使用更灵活的语法完成工作。
申请存档
下面的pythonscript将“FROM”(而不是“notFrom”)替换为“TO”。
regex_replace.py
import sys
import re
for line in sys.stdin:
line = re.sub(r'(?<!not)FROM', 'TO', line)
sys.stdout.write(line)
你可以把它应用在文本文件上,比如
$ cat test.txt
bla notFROM
FROM FROM
bla bla
FROM bla
bla notFROM FROM
bla FROM
bla bla
$ cat test.txt | python regex_replace.py
bla notFROM
TO TO
bla bla
TO bla
bla notFROM TO
bla TO
bla bla
应用于变量
#!/bin/bash
hello=ho02123ware38384you443d34o3434ingtod38384day
echo $hello
PYTHON_CODE=$(cat <<END
import sys
import re
for line in sys.stdin:
line = re.sub(r'[0-9]', '', line)
sys.stdout.write(line)
END
)
echo $hello | python -c "$PYTHON_CODE"
输出
ho02123ware38384you443d34o3434ingtod38384day
howareyoudoingtodday