Regex 在bash中解析带有两个捕获的字符串

Regex 在bash中解析带有两个捕获的字符串,regex,bash,Regex,Bash,我正在尝试用正则表达式解析字符串。有效字符串的格式如下: https://github.com/xyz/abc/a_123/project_14.git 有效字符串应包含github.com和xyz或zyx。如果字符串有效,我想将abc/a_123捕获到$a中,并将project_14捕获到$B中 我所做的: if [[ "$x" == *"github.com"* ]]; then if [[ "$x" == *"xyz"* ]]; then # (1) el

我正在尝试用正则表达式解析字符串。有效字符串的格式如下:

https://github.com/xyz/abc/a_123/project_14.git
有效字符串应包含
github.com
xyz
zyx
。如果字符串有效,我想将
abc/a_123
捕获到
$a
中,并将
project_14
捕获到
$B

我所做的:

if [[ "$x" == *"github.com"* ]]; then
    if [[ "$x" == *"xyz"* ]]; then
        # (1)
    elif [[ "$x" == *"zyx"* ]]; then
        # (2)
    else
        return 1 # Invalid
    fi
    return 0 # Valid
fi
return 1 # Invalid
(1)
(2)
中,我想用值设置
$A
$B
(不同情况下的行为相同)。 另外,我认为这个解决方案不好,因为在
https://github.com/bla/abc/a_123/xyz.git
所以我想我们需要将其更改为
“github.com/xyz”
。另外,如何摆脱
.git
(如果存在)

另一个例子:

https://github.com/zyx/asdasdas/lalal/asdas/nu.git
# $A = asdasdas/lalal/asdas
# $B = nu

实现这个目标的正确方法是什么?

我想这正是你想要的:

#!/bin/bash

repo="https://github.com/xyz/abc/a_123/project_14.git"

[[ ! "$repo" =~ https:\/\/github.com\/[a-z]+\/[a-z]+\/[a-z]_[0-9]+\/.*.git ]] && exit

A=$( echo "$repo" | sed -E "s/(https:\/\/github.com\/[a-z]+)(\/[a-z]+\/[a-z]_[0-9]+\/)(.*.git)/\2/g" )
B=$( echo "$repo" | sed -E "s/(https:\/\/github.com\/[a-z]+)(\/[a-z]+\/[a-z]_[0-9]+\/)(.*.git)/\3/g" )

echo "$A"
echo "${B%%.git}"

让我知道它是否有用这里有一种使用正则表达式的方法:

url='https://github.com/xyz/abc/a_123/project_14.git'

if [[ $url =~ http[s]?:[/]{2}(github.com)[/]([[:alpha:]]+)(/.*)$ ]] 
then    
    $A=${BASH_REMATCH[2]}
    $B=${BASH_REMATCH[3]%.git}
fi
下面是一个小的概念证明:

url='https://github.com/xyz/abc/a_123/project_14.git'

if [[ $url =~ http[s]?:[/]{2}(github.com)[/]([[:alpha:]]+)(/.*)$ ]]
then
   echo ${BASH_REMATCH[2]} ${BASH_REMATCH[3]%.git}
fi
导致:

xyz /abc/a_123/project_14

请您尝试以下方法:

strchk() {
    local x=$1
    if [[ $x =~ github.com/(xyz|zyx)/(.+)/(.+) ]]; then
        A="${BASH_REMATCH[2]}"
        B="${BASH_REMATCH[3]%.*}"
        return 0
    else
        return 1
    fi
}
结果:

strchk "https://github.com/xyz/abc/a_123/project_14.git" && echo "A=$A, B=$B"
=> A=abc/a_123, B=project_14
strchk "https://github.com/bla/abc/a_123/xyz.git" && echo "A=$A, B=$B"
=> <empty>
strchk "https://github.com/zyx/asdasdas/lalal/asdas/nu.git" && echo "A=$A, B=$B"
=> A=asdasdas/lalal/asdas, B=nu
strchk”https://github.com/xyz/abc/a_123/project_14.git&&echo“A=$A,B=$B”
=>A=abc/A\U 123,B=project\U 14
strchk“https://github.com/bla/abc/a_123/xyz.git&&echo“A=$A,B=$B”
=> 
strchk“https://github.com/zyx/asdasdas/lalal/asdas/nu.git&&echo“A=$A,B=$B”
=>A=asdasdas/lalal/asdas,B=nu
说明:

  • 模式
    github.com/(xyz | zyx)/
    与包含
    github.com/
    后跟
    xyz/
    zyx/
  • 下一个模式
    (.+)/
    xyz/
    zyx/
    后面的子字符串匹配,长度相同 当它到达最右边的斜线时,将捕获的子字符串存储在parens中 bash变量
    ${bash_REMATCH[2]}
  • 最后一个模式
    (.+)
    将剩余的子字符串捕获到
    ${BASH_重新匹配[3]}
  • 参数扩展
    ${BASH_REMATCH[3]].}
    删除扩展名 在点之后,如果存在

希望这有帮助。

查找bash
=~
regex操作符。它可以让您进行比
==
更复杂的匹配,并且可以捕获变量。它将它们保存在一个名为
$BASH_REMATCH
——另一个很好的搜索词的数组中。一个好的开始可以是
[$url=~http[s]?:[/]{2}(github.com)[/]([:alpha:]+/([:alpha:]+])/.[.]git]$]&&echo${BASH_REMATCH[*]}
,然后将这些匹配作为
${BASH_REMATCH}的索引
如您所见。
sed
awk
对于您希望检查正则表达式并提取部分字符串的情况是非常有用的朋友。它将与
https://github.com/bla/abc/a_123/xyz.git
OP想要排除哪些,不是吗?会的,但据我所知,OP想要的,如果我们有办法删除后缀
.git
。正如我的回答所示,我们已经做到了。如果我不清楚的话,很抱歉,但我担心的是子字符串
github.com/
后面跟着
bla
,而不是
xyz
zyx
。哦!我懂了。据我所知,OP将其作为一个通用示例,但我可能弄错了。