regex - shell 脚本。如何使用正则表达式提取字符串

标签 regex shell curl

我是 shell 脚本的新手。我想使用 curl 发送一个 http 请求,然后使用正则表达式提取一些字符串。例如,如何从 http 响应中提取域名? (示例仅供学习之用)

#!/bin/bash
name=$(curl google.com | grep "www\..*com")
echo "domain name is"
echo $name

最佳答案

使用 bash regular expressions :

re="http://([^/]+)/"
if [[ $name =~ $re ]]; then echo ${BASH_REMATCH[1]}; fi

编辑 - OP 要求解释语法。 Regular expression syntax是一个很大的话题,我无法在这里完整解释,但我将尝试解释足够的内容以理解示例。
re="http://([^/]+)/"

这是存储在 bash 变量中的正则表达式,re - 即您希望输入字符串匹配的内容,并希望提取子字符串。分解它:
  • http://只是一个字符串 - 输入字符串必须包含此子字符串,正则表达式才能匹配
  • []通常使用方括号说“匹配括号内的任何字符”。所以c[ao]t将匹配“cat”和“cot”。 ^ [] 内的字符将此修改为“匹配方括号内的字符以外的任何字符。因此,在这种情况下,[^/] 将匹配除“/”之外的任何字符。
  • 方括号表达式只会匹配一个字符。添加 +它的末尾说“匹配 1 个或多个前面的子表达式”。所以[^/]+匹配 1 个或多个所有字符的集合,不包括“/”。
  • 推杆 ()子表达式周围的括号表示您要保存与该子表达式匹配的任何内容以供以后处理。如果您使用的语言支持这一点,它将提供一些机制来检索这些子匹配。对于 bash,它是 BASH_REMATCH 数组。
  • 最后,我们对“/”进行精确匹配,以确保我们一直匹配到完全限定域名的结尾和后面的“/”

  • 接下来,我们必须根据正则表达式测试输入字符串以查看它是否匹配。我们可以使用 bash 条件来做到这一点:
    if [[ $name =~ $re ]]; then
        echo ${BASH_REMATCH[1]}
    fi
    

    在 bash 中,[[ ]]指定扩展条件测试,并且可能包含 =~ bash 正则表达式运算符。在这种情况下,我们测试输入字符串 $name 是否匹配正则表达式 $re .如果它匹配,那么由于正则表达式的构造,我们可以保证我们将有一个子匹配(来自括号 ()),我们可以使用 BASH_REMATCH 数组访问它:
  • 此数组的元素 0 ${BASH_REMATCH[0]}将是正则表达式匹配的整个字符串,即“http://www.google.com/”。
  • 此数组的后续元素将是子匹配的后续结果。请注意,您可以有多个子匹配 ()在正则表达式中 - BASH_REMATCH元素将按顺序与这些相对应。所以在这种情况下 ${BASH_REMATCH[1]}将包含“www.google.com”,我认为这是您想要的字符串。

  • 注意 BASH_REMATCH 数组的内容只适用于最后一次正则表达式 =~使用了运算符。所以如果你继续做更多的正则表达式匹配,你 必须每次都从这个数组中保存你需要的内容。

    这似乎是一个冗长的描述,但我确实掩盖了正则表达式的几个复杂之处。它们可以非常强大,我相信性能不错,但正则表达式语法很复杂。正则表达式的实现也各不相同,因此不同的语言将支持不同的功能,并且在语法上可能会有细微的差异。特别是在正则表达式中转义字符可能是一个棘手的问题,尤其是当这些字符在给定语言中具有不同的含义时。

    请注意,不是设置 $re变量放在单独的一行,并在条件中引用此变量,您可以将正则表达式直接放入条件中。然而在 bash 3.2 ,关于是否需要在此类文字正则表达式周围使用引号的规则已更改。将正则表达式放在单独的变量中是解决此问题的直接方法,以便条件在支持 =~ 的所有 bash 版本中按预期工作。匹配运算符。

    关于regex - shell 脚本。如何使用正则表达式提取字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19737675/

    相关文章:

    mysql - 如何在Linux命令提示符下使用存储过程

    bash - shell 脚本 : Using bash with xargs

    linux - Linux 上使用 Curl 的 Azure 存储表 API REST

    php - Zend2 发布请求

    javascript - 在网页上进行文本替换的最简洁方法? (使用 GreaseMonkey)

    java - 使用正则表达式限制特殊字符

    第一次匹配时使用或使用第二个正则表达式的正则表达式?

    linux - 在文本文件的指定字段中提取包含单词的行

    php - php、selenium 和 chromedriver 的 WebdriverCurlException

    objective-c - 过滤文本的正则表达式