Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use regex variable in zsh?

How can I use a regex variable in zsh the same way it works in bash? I can only get zsh to work with an inline regex. I am just trying to test a string only contains alphanumerics, underscores or periods, but no dashes. As you can see, the inline regex and the regex variable work as expected in bash, but zsh only matches the inline regex.

Bash

#!/bin/bash

RE='[0-9A-Za-z_\.]'

for test in $@; do
    echo -e "bash test: $test"

    if [[ "${test//[0-9A-Za-z_\.]/}" = "" ]]; then
        echo -e '\tmatch inline'
    fi

    if [[ "${test//$RE/}" = "" ]]; then
        echo -e '\tmatch var'
    fi

done

❯./bash-regex-test.sh foo_bar foo-bar

output:


bash test: foo_bar
        match inline
        match var
bash test: foo-bar

Zsh

#!/bin/zsh


RE='[0-9A-Za-z_\.]'

for test in $@; do
    echo "zsh test: $test"

    if [[ "${test//[0-9A-Za-z_\.]/}" = "" ]]; then
        echo '\tmatch inline'
    fi

    if [[ "${test//$RE/}" = "" ]]; then
        echo '\tmatch var'
    fi

done

❯./zsh-regex-test.zsh foo_bar foo-bar

output:

zsh test: foo_bar
        match inline
zsh test: foo-bar

like image 398
ram Avatar asked Oct 13 '25 11:10

ram


1 Answers

With zsh you need to use ${~RE} instead of $RE so the variable $RE is treated as a pattern, not the literal string. Then change the line as:

    if [[ "${test//${~RE}/}" = "" ]]; then

BTW your usage of $RE is not the regex but the pattern as in pathname expansion.
In order to use it as a regex, you'll need to use =~ operator as:

#!/bin/zsh

RE='^[0-9A-Za-z_\.]+$'

for test in "$@"; do
    echo "zsh test: $test"

    if [[ $test =~ ^[0-9A-Za-z_\.]+$ ]]; then
        echo '\tmatch inline'
    fi

    if [[ $test =~ $RE ]]; then
        echo '\tmatch var'
    fi

done
like image 172
tshiono Avatar answered Oct 15 '25 04:10

tshiono