Jorge Perez
Jorge Perez

Reputation: 47

Check if a string contains "-" and "]" at the same time

I have the next two regex in Bash:

1.^[-a-zA-Z0-9\,\.\;\:]*$
2.^[]a-zA-Z0-9\,\.\;\:]*$

The first matches when the string contains a "-" and the other values. The second when contains a "]". I put this values at the beginning of my regex because I can't scape them. How I can get match the two values at the same time?

Upvotes: 0

Views: 104

Answers (4)

user2350426
user2350426

Reputation:

There are two questions in your post.

  1. One is in the description:

    How I can get match the two values at the same time?

    That is an OR match, which could be done with a range that mix your two ranges:

    pattern='^[]a-zA-Z0-9,.;:-]*$'
    

    That will match a line that either contains one (or several) -OR]OR any of the included characters. That would be all the lines (except ?????, ++++++ and as df gh) in the test script below.

  2. Two is in the title:

    … a string contains “-” and “]” at the same time

    That is an AND match. The simplest (and slowest) way to do it is:

    echo "$line"  |  grep '-'  |  grep ']'   |  grep '^[-a-zA-Z0-9,.;:]*$'
    

    The first two calls to grep select only the lines that:

    contain both (one or several) - and (one or several) ]

Test script:

#!/bin/bash

printlines(){
cat <<-\_test_lines_
asdfgh
asdfgh-
asdfgh]
as]df
as,df
as.df
as;df
as:df
as-df
as]]]df
as---df
asAS]]]DFdf
as123--456DF
as,.;:-df
as-dfg]h
as]dfg-h
a]s]d]f]g]h
a]s]d]f]g]h-
s-t-r-i-n-g]
as]df-gh
123]asdefgh
123asd-fgh-
?????
++++++
as df gh
_test_lines_
}

pattern='^[]a-zA-Z0-9,.;:-]*$'

printf '%s\n' "Testing the simple pattern of $pattern"
while read line; do
    resultgrep="$(  echo "$line" | grep "$pattern"  )"
    printf '%13s %-13s\n' "$line" "$resultgrep"
done < <(printlines)
echo "#############################################################"
echo

p1='-'; p2=']'; p3='^[]a-zA-Z0-9,.;:-]*$'

printf '%s\n' "Testing a 'grep AND' of '$p1', '$p2' and  '$p3'."
while read line; do
    resultgrep="$(  echo "$line" | grep "$p1" | grep "$p2" | grep "$p3"  )"
    [[ $resultgrep ]] && printf '%13s %-13s\n' "$line" "$resultgrep"
done < <(printlines)
echo "#############################################################"
echo

printf '%s\n' "Testing an 'AWK AND' of '$p1', '$p2' and  '$p3'."
while read line; do
    resultawk="$(  echo "$line" | 
    awk -v p1="$p1" -v p2="$p2" -v p3="$p3" '$0~p1 && $0~p2 && $0~p3' )"
    [[ $resultawk ]] && printf '%13s %-13s\n' "$line" "$resultawk"
done < <(printlines)
echo "#############################################################"
echo

printf '%s\n' "Testing a 'bash AND' of '$p1', '$p2' and  '$p3'."
while read line; do
    rgrep="$(  echo "$line" | grep "$p1" | grep "$p2" | grep "$p3"  )"
    [[ ( $line =~ $p1 ) && ( $line =~ $p2 ) && ( $line =~ $p3 ) ]]
    rbash=${BASH_REMATCH[0]}
    [[ $rbash ]] && printf '%13s %-13s %-13s\n' "$line" "$rgrep" "$rbash"
done < <(printlines)
echo "#############################################################"
echo

Upvotes: 0

hek2mgl
hek2mgl

Reputation: 158100

Basically you can use this:

grep -E '^.*\-.*\[|\[.*\-.*$'

It matches either a - followed by zero or more arbitrary chars and a [ or a [ followed by zero or more chars and a -

However since you don't accept arbitrary chars, you need to change it to:

grep -E '^[a-zA-Z0-9,.;:]*\-[a-zA-Z0-9,.;:]*\[|\[[a-zA-Z0-9,.;:]*\-[a-zA-Z0-9,.;:]*$'

Upvotes: 1

Mustafa DOGRU
Mustafa DOGRU

Reputation: 4112

Maybe, this can help you

#!/bin/bash
while read p; do
echo $p | grep -E '\-.*\]|\].*\-' | grep "^[]a-zA-Z0-9,.;:-]*$"
done <$1

user-host:/tmp$ cat test
-i]string
]adfadfa-
string-
]string
str]ing
]123string
123string-
?????
++++++


user-host:/tmp$ ./test.sh test
-i]string
]adfadfa-

Upvotes: 0

chepner
chepner

Reputation: 531808

You can also place the - at the end of the bracket expression, since a range must be closed on both ends.

^[]a-zA-Z0-9,.;:-]*$

You don't have to escape any of the other characters, either. Colons, semicolons, and commas have no special meaning in any part of a regular expression, and while a period loses its special meaning inside a bracket expression.

Upvotes: 2

Related Questions