我看过这个例子:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
遵循以下语法:${variable//pattern/replacement}
不幸的是,模式字段似乎不支持完整的正则表达式语法(如果我使用。或者\s,例如,它试图匹配文字字符)。
我如何使用完整的正则表达式语法搜索/替换字符串?
我看过这个例子:
hello=ho02123ware38384you443d34o3434ingtod38384day
echo ${hello//[0-9]/}
遵循以下语法:${variable//pattern/replacement}
不幸的是,模式字段似乎不支持完整的正则表达式语法(如果我使用。或者\s,例如,它试图匹配文字字符)。
我如何使用完整的正则表达式语法搜索/替换字符串?
当前回答
设置var
hello=ho02123ware38384you443d34o3434ingtod38384day
然后,在var上用regex替换echo
echo ${hello//[[:digit:]]/}
这将打印:
howareyoudoingtodday
额外-如果你想要相反的(获得数字字符)
echo ${hello//[![:digit:]]/}
这将打印:
021233838444334343438384
其他回答
使用[[:digit:]](注意双括号)作为模式:
$ hello=ho02123ware38384you443d34o3434ingtod38384day
$ echo ${hello//[[:digit:]]/}
howareyoudoingtodday
只是想总结一下答案(尤其是@nickl-的https://stackoverflow.com/a/22261334/2916086)。
这实际上可以在纯bash中完成:
hello=ho02123ware38384you443d34o3434ingtod38384day
re='(.*)[0-9]+(.*)'
while [[ $hello =~ $re ]]; do
hello=${BASH_REMATCH[1]}${BASH_REMATCH[2]}
done
echo "$hello"
收益率…
howareyoudoingtodday
你可以使用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
设置var
hello=ho02123ware38384you443d34o3434ingtod38384day
然后,在var上用regex替换echo
echo ${hello//[[:digit:]]/}
这将打印:
howareyoudoingtodday
额外-如果你想要相反的(获得数字字符)
echo ${hello//[![:digit:]]/}
这将打印:
021233838444334343438384
我知道这是一个古老的线程,但它是我在谷歌上的第一次点击,我想分享以下我放在一起的resub,它增加了对多个$1,$2等反向引用的支持…
#!/usr/bin/env bash
############################################
### resub - regex substitution in bash ###
############################################
resub() {
local match="$1" subst="$2" tmp
if [[ -z $match ]]; then
echo "Usage: echo \"some text\" | resub '(.*) (.*)' '\$2 me \${1}time'" >&2
return 1
fi
### First, convert "$1" to "$BASH_REMATCH[1]" and 'single-quote' for later eval-ing...
### Utility function to 'single-quote' a list of strings
squot() { local a=(); for i in "$@"; do a+=( $(echo \'${i//\'/\'\"\'\"\'}\' )); done; echo "${a[@]}"; }
tmp=""
while [[ $subst =~ (.*)\${([0-9]+)}(.*) ]] || [[ $subst =~ (.*)\$([0-9]+)(.*) ]]; do
tmp="\${BASH_REMATCH[${BASH_REMATCH[2]}]}$(squot "${BASH_REMATCH[3]}")${tmp}"
subst="${BASH_REMATCH[1]}"
done
subst="$(squot "${subst}")${tmp}"
### Now start (globally) substituting
tmp=""
while read line; do
counter=0
while [[ $line =~ $match(.*) ]]; do
eval tmp='"${tmp}${line%${BASH_REMATCH[0]}}"'"${subst}"
line="${BASH_REMATCH[$(( ${#BASH_REMATCH[@]} - 1 ))]}"
done
echo "${tmp}${line}"
done
}
resub "$@"
##################
### EXAMPLES ###
##################
### % echo "The quick brown fox jumps quickly over the lazy dog" | resub quick slow
### The slow brown fox jumps slowly over the lazy dog
### % echo "The quick brown fox jumps quickly over the lazy dog" | resub 'quick ([^ ]+) fox' 'slow $1 sheep'
### The slow brown sheep jumps quickly over the lazy dog
### % animal="sheep"
### % echo "The quick brown fox 'jumps' quickly over the \"lazy\" \$dog" | resub 'quick ([^ ]+) fox' "\"\$low\" \${1} '$animal'"
### The "$low" brown 'sheep' 'jumps' quickly over the "lazy" $dog
### % echo "one two three four five" | resub "one ([^ ]+) three ([^ ]+) five" 'one $2 three $1 five'
### one four three two five
### % echo "one two one four five" | resub "one ([^ ]+) " 'XXX $1 '
### XXX two XXX four five
### % echo "one two three four five one six three seven eight" | resub "one ([^ ]+) three ([^ ]+) " 'XXX $1 YYY $2 '
### XXX two YYY four five XXX six YYY seven eight
H/T @Charles Duffy回复:(.*)$match(.*)