【问题标题】:'$' in regexp in bash'$' 在 bash 中的正则表达式
【发布时间】:2019-08-10 08:39:37
【问题描述】:

我真的不知道我在做什么。 在变量 a 中,我想在“比特币”第一次出现之后找到“$”的第一次出现,并打印它之后的所有内容,直到第一个换行符。 我有以下代码:

a = 'something Bitcoin something againe $jjjkjk\n againe something'
if [[ $a =~ .*Bitcoin.*[\$](.*).* ]]; then
    echo "${BASH_REMATCH[1]}" 
else
echo "no"
fi

在这个例子中,我想得到'jjjkjk'。我得到的只是“不”。 这段代码可能真的有缺陷,我没有这方面的经验。我认为问题可能出在“$”符号上。请帮忙!

【问题讨论】:

  • 试试ideone.com/pvPKSE。请注意,您的 a 声明不正确,并且它内部没有 $ ,因为它是插值的。此外,您正在尝试将 PCRE 正则表达式与 Bash 一起使用,这是不对的。 . 这里匹配任何字符,包括换行符。 [\s\S] 匹配 \sS
  • Ty,这很有帮助。我编辑了代码,但还是不太好。(我是否正确地编辑了它?)
  • 不,不对,你的字符串没有换行符。

标签: regex bash shell


【解决方案1】:

使用 ANSI-C Quoting 正确处理 bash 中的换行符 -- \n 序列变成文字换行符。

a=$'something Bitcoin something againe $jjjkjk\n againe something'
regex=$'Bitcoin[^$]*[$]([^\n]+)'
[[ $a =~ $regex ]] && declare -p BASH_REMATCH
declare -ar BASH_REMATCH='([0]="Bitcoin something againe \$jjjkjk" [1]="jjjkjk")'
# .................................................................^^^^^^^^^^^^

验证内容是否包含换行符:

$ printf '%s' "$regex" | od -c
0000000   B   i   t   c   o   i   n   [   ^   $   ]   *   [   $   ]   (
0000020   [   ^  \n   ]   +   )
0000026

【讨论】:

    【解决方案2】:

    这是您的代码的工作版本:

    a='something Bitcoin something againe $jjjkjk\n againe something'
    r=".*Bitcoin.*[\$]([^\n]*).*"
    if [[ $a =~ $r ]]; then
        echo "${BASH_REMATCH[1]}" 
    else
    echo "no"
    fi
    

    你需要找到 'Bitcoin' 然后在它后面找到一个 '$',不管它之间是什么,所以你应该使用.* 操作符,当你想捕获一些文本直到一个特定的字符时,最好的方法正在使用 [^](not) 运算符,在您的情况下:[^\n] 这意味着捕获所有内容,直到 \n

    您的变量声明也有问题。 a = "..." 无效,空间浪费。所以正确的是'a=".."`。

    使用双引号也是错误的,这会将美元符号替换为空变量(evaluation

    【讨论】:

    • [^\n] 匹配除\n 之外的任何字符。它不匹配任何字符,而是换行符。此外,a='something Bitcoin something againe $jjjkjk\n againe something' 也没有换行符。
    • 如果a'something Bitcoin something $ stuff OP wants to capture $other stuff\n etc,那么在Bitcoin 之后使用.* 匹配只会匹配other stuff,因为.* 是“贪婪的”并且会尽可能多地消耗。所以也许使用[^\$]* 而不是.*
    • @WiktorStribiżew 我添加了反斜杠来转义$,因为他在双引号字符串中定义了正则表达式。而且我并不是说这个改变本身就可以修复正则表达式。只是它会防止贪婪地跳过输入中的多个 $ 字符。
    • 是的,但它仍然无法解决这种方法。 [^\n] 这意味着捕获所有内容,直到 \n 出错。
    • @WiktorStribiżew 如果通过“这种方法”,您的意思是一般的 Saeed 解决方案,那么我并没有说它会解决整个解决方案。我的评论只涉及不使用.*,因为它可能会跳过多个$ 字符。如果您指的是我的解决方法,那么是的,我认为我的方法需要一个额外的反斜杠来区分字符 '$' 和表示行尾的正则表达式元字符 $。但是除了缺少额外的反斜杠之外,是的,它确实解决了.* 过于贪婪的问题。
    猜你喜欢
    • 1970-01-01
    • 2013-07-13
    • 1970-01-01
    • 2019-08-04
    • 2013-06-06
    • 1970-01-01
    • 2016-11-11
    • 2018-04-16
    • 2011-11-01
    相关资源
    最近更新 更多