我想使用正则表达式提取字符串的一部分。例如,如何从$name变量中提取域名?
$name
name='<A HREF="http://www.google.com/">here</A>' domain_name=... # apply some regex on $name
flvtvl501#
使用bash正则表达式:
re="http://([^/]+)/" if [[ $name =~ $re ]]; then echo ${BASH_REMATCH[1]}; fi
Edit- OP要求解释语法。Regular expression syntax是一个很大的主题,我无法在这里完整地解释,但我将尝试解释足够的内容来理解示例。
re="http://([^/]+)/"
这是一个存储在bash变量re中的正则表达式--即您希望输入字符串匹配的内容,并希望从中提取一个子字符串。
re
http://
[]
c[ao]t
^
[^/]
+
[^/]+
()
接下来,我们需要根据正则表达式测试输入字符串,看看它是否匹配。我们可以使用bash条件来完成这一任务:
if [[ $name =~ $re ]]; then echo ${BASH_REMATCH[1]} fi
在bash中,[[ ]]指定扩展的条件测试,并且可能包含=~ bash正则表达式运算符。在本例中,我们测试输入字符串$name是否与正则表达式$re匹配。如果匹配,则由于正则表达式的构造,我们保证会有一个子匹配(从圆括号()开始),我们可以使用BASH_REMATCH数组访问它:
[[ ]]
=~
$re
${BASH_REMATCH[0]}
BASH_REMATCH
${BASH_REMATCH[1]}
注意,BASH_REMATCH数组的内容只适用于最后一次使用正则表达式=~运算符时,所以如果您继续执行更多的正则表达式匹配,您必须每次都从该数组保存所需的内容。这可能看起来是一个冗长的描述,但我确实掩盖了正则表达式的几个错综复杂之处。它们可以相当强大,我相信性能也不错,但正则表达式语法很复杂。而且正则表达式的实现也各不相同,因此不同的语言将支持不同的特征并且可能在语法上有细微的差别。特别是正则表达式中的字符转义可能是一个棘手的问题,尤其是当这些字符在给定的语言中具有不同的含义时。请注意,您可以将正则表达式直接放入条件中,而不是在单独的行中设置$re变量并在条件中引用此变量。但是在bash 3.2中,更改了有关此类文字正则表达式是否需要引号的规则。将正则表达式放入单独的变量中是解决此问题的直接方法。以便该条件在支持=~匹配运算符的所有bash版本中按预期工作。
aamkag612#
一种方法是使用sed。例如:
sed
echo $name | sed -e 's?http://www\.??'
通常,sed正则表达式用'/'分隔,但你可以用'?',因为你要搜索'/'。这里有另一个bash技巧。@DigitalTrauma的回答提醒了我,我应该建议它。它是类似的:
echo ${name#http://www.}
(DigitalTrauma还提醒我需要处理“http://”。)
2条答案
按热度按时间flvtvl501#
使用bash正则表达式:
Edit- OP要求解释语法。Regular expression syntax是一个很大的主题,我无法在这里完整地解释,但我将尝试解释足够的内容来理解示例。
这是一个存储在bash变量
re
中的正则表达式--即您希望输入字符串匹配的内容,并希望从中提取一个子字符串。http://
只是一个字符串-输入字符串必须包含此子字符串,正则表达式才能匹配[]
通常使用方括号表示“匹配方括号内的任何字符”。因此c[ao]t
将匹配“cat”和“cot”。[]
中的^
字符将其修改为“匹配方括号内的任何字符 * 除外 *。因此在本例中[^/]
将匹配除“/"以外的任何字符。+
表示“匹配前面子表达式的一个或多个”。因此[^/]+
匹配所有字符集中的一个或多个,不包括“/"。()
圆括号表示您希望保存与该子表达式匹配的任何内容以供以后处理。如果您使用的语言支持这一点,它将提供一些机制来检索这些子匹配项。对于bash,它是BASH_REMATCH数组。接下来,我们需要根据正则表达式测试输入字符串,看看它是否匹配。我们可以使用bash条件来完成这一任务:
在bash中,
[[ ]]
指定扩展的条件测试,并且可能包含=~
bash正则表达式运算符。在本例中,我们测试输入字符串$name
是否与正则表达式$re
匹配。如果匹配,则由于正则表达式的构造,我们保证会有一个子匹配(从圆括号()
开始),我们可以使用BASH_REMATCH数组访问它:${BASH_REMATCH[0]}
的元素0将是正则表达式匹配的整个字符串,即“http://www.google.com/“。()
-BASH_REMATCH
元素将依次对应这些子匹配。所以在这个例子中${BASH_REMATCH[1]}
将包含“www.google.com“,我认为这是你想要的字符串。注意,BASH_REMATCH数组的内容只适用于最后一次使用正则表达式
=~
运算符时,所以如果您继续执行更多的正则表达式匹配,您必须每次都从该数组保存所需的内容。这可能看起来是一个冗长的描述,但我确实掩盖了正则表达式的几个错综复杂之处。它们可以相当强大,我相信性能也不错,但正则表达式语法很复杂。而且正则表达式的实现也各不相同,因此不同的语言将支持不同的特征并且可能在语法上有细微的差别。特别是正则表达式中的字符转义可能是一个棘手的问题,尤其是当这些字符在给定的语言中具有不同的含义时。
请注意,您可以将正则表达式直接放入条件中,而不是在单独的行中设置
$re
变量并在条件中引用此变量。但是在bash 3.2中,更改了有关此类文字正则表达式是否需要引号的规则。将正则表达式放入单独的变量中是解决此问题的直接方法。以便该条件在支持=~
匹配运算符的所有bash版本中按预期工作。aamkag612#
一种方法是使用
sed
。例如:通常,
sed
正则表达式用'/'分隔,但你可以用'?',因为你要搜索'/'。这里有另一个bash技巧。@DigitalTrauma的回答提醒了我,我应该建议它。它是类似的:(DigitalTrauma还提醒我需要处理“http://”。)