I'd like to extract the port number from an address string. The whole string looks like this:
connect single-cluster --listen-addr=127.0.0.1:12345 --filename=hello
or
connect single-cluster --listen-addr=127.0.0.1 --filename=hello
I'd like to save the address and port from the listen-addr
to two variables: ADDR
and PORT
. If the port does not exist in the input string, just leave the PORT
variable empty, and set the ADDR
.
Now if the port number exists in the input string, I can use this regex:
ORI_STR="connect single-cluster --listen-addr=127.0.0.1:12345 --filename=hello"
LISTEN_ADDR_REGEX="(^|[[:space:]])--listen-addr=(([^[:space:]] ):([^[:space:]] ))($|[[:space:]])"
[[ $ORI_STR =~ $LISTEN_ADDR_REGEX ]] && ADDR=${BASH_REMATCH[3]} && PORT=${BASH_REMATCH[4]}
echo "ADDR=$ADDR"
echo "PORT=$PORT"
This gives me:
ADDR=127.0.0.1
PORT=12345
But I don't know how to include the case that the port number is not set in the original string. (i.e. there's no :12345
in the ORI_STR
).
CodePudding user response:
This works with or without the port:
LISTEN_ADDR_REGEX="(^|[[:space:]])--listen-addr=(([^[:space:]:] )(:([^[:space:]] ))?)($|[[:space:]])"
# ^ ^ ^^
[[ $ORI_STR =~ $LISTEN_ADDR_REGEX ]] && ADDR=${BASH_REMATCH[3]} && PORT=${BASH_REMATCH[5]}
# ^
echo "ADDR=$ADDR"
echo "PORT=$PORT"
I added parentheses around the :port
part and marked it optional with ?
. That moved the port from match group 4
to 5
. I also added :
to the exclusion list for the IP address; without that the IP was greedily matching the port.
It's kind of hard to spot the differences so I marked them with ^
carets.
CodePudding user response:
A ?
means zero or one match.
#!/usr/bin/env bash
#ori_str="connect single-cluster --listen-addr=127.0.0.1:12345 --filename=hello"
ori_str="connect single-cluster --listen-addr=127.0.0.1 --filename=hello"
listen_addr_regex="^.* --listen-addr=([^:] )(:)?([^[:space:]] )? .*$"
[[ $ori_str =~ $listen_addr_regex ]] && addr=${BASH_REMATCH[1]} && port=${BASH_REMATCH[3]}
echo "addr=$addr"
echo "port=$port"
- Use
"${port:-none}"
to usenone
as the default value or changenone
to something else if needed