【问题标题】:Regex works in Rubular but not in bash正则表达式适用于 Rubular 但不适用于 bash
【发布时间】:2013-09-24 23:02:23
【问题描述】:

给定一个字符串,如:

one/two one/three two/four five/six seven

我使用这个正则表达式:

(?<=\s)([^\/]*)(?=\/|\s)(?!.*\1\b)

得到:

one
two
five
seven

这是我想要的结果。所有唯一的“根”字符串。它适用于Rubular,但 bash 不返回任何匹配项。

我知道我正在使用的正则表达式包含一个感叹号,这会使 bash 感到困惑,但是在它前面添加一个斜杠转义字符没有帮助,单引号也没有帮助。

我在 bash 中这样使用它:

[[ $string =~ (?<=\s)([^\/]*)(?=\/|\s)(?!.*\1\b) ]] echo ${BASH_REMATCH}

我不能对正则表达式使用双引号,因为我使用的 bash 版本将双引号中的内容解释为文字字符串。

如何让 bash 理解这个正则表达式?

【问题讨论】:

  • 相当肯定 bash 不理解环视。
  • 嗯,是的,这可能对我有用。非常感谢!我想知道是否可以在不使用环视的情况下将我想要的内容与 bash 中的正则表达式相匹配...
  • 是的。我想 Rubular 检查并不完全有效。我希望有一些方法可以为 bash 创建一个类似的正则表达式。不过,根据@FrankieTheKneeMan 的说法,这可能是不可能的,或者至少不能通过环视来实现。

标签: regex string bash unix


【解决方案1】:

Bash 绝对不理解 perl 兼容的正则表达式。我会坚持使用 bash 习语:

string="one/two one/three two/four five/six seven"
roots=$(sed 's/\/[^[:blank:]]*//g' <<< "$string" | tr ' ' '\n' | sort -u)
echo "$roots"

roots=()                        # empty array
for word in $string             # no quotes to obtain word splitting
do
    roots+=( ${word%/*} )       # add to the array the bit before the last slash
done
printf "%s\n" "${roots[@]}" | sort -u

或者,对于 bash 4,使用关联数组来模拟集合的行为。

declare -A roots                # an associative array
for word in $string             # no quotes to obtain word splitting
do
    roots[${word%/*}]=1
done
printf "%s\n" "${!roots[@]}"    # print out the hash keys

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多