Grep regular expression for digits in character st

2019-07-19 15:29发布

I need some way to find words that contain any combination of characters and digits but exactly 4 digits only, and at least one character.

EXAMPLE:

a1a1a1a1        // Match
1234            // NO match (no characters)
a1a1a1a1a1      // NO match
ab2b2           // NO match
cd12            // NO match
z9989           // Match
1ab26a9         // Match
1ab1c1          // NO match
12345           // NO match
24              // NO match
a2b2c2d2        // Match
ab11cd22dd33    // NO match

标签: regex shell grep
9条回答
我命由我不由天
2楼-- · 2019-07-19 15:58

to match a digit in grep you can use [0-9]. To match anything but a digit, you can use [^0-9]. Since that can be any number of , or no chars, you add a "*" (any number of the preceding). So what you'll want is logically

(anything not a digit or nothing)* (any single digit) (anything not a digit or nothing)* ....

until you have 4 "any single digit" groups. i.e. [^0-9]*[0-9]...

I find with grep long patterns, especially with long strings of special chars that need to be escaped, it's best to build up slowly so you're sure you understand whats going on. For example,

#this will highlight your matches, and make it easier to understand
alias grep='grep --color=auto'
echo 'a1b2' | grep '[0-9]' 

will show you how it's matching. You can then extend the pattern once you understand each part.

查看更多
干净又极端
3楼-- · 2019-07-19 16:00

You might try

[^0-9]*[0-9][^0-9]*[0-9][^0-9]*[0-9][^0-9]*[0-9][^0-9]*

But this will match 1234. why doesn't that match your criteria?

查看更多
我命由我不由天
4楼-- · 2019-07-19 16:00

you can use normal shell script, no need complicated regex.

var=a1a1a1a1
alldigits=${var//[^0-9]/}
allletters=${var//[0-9]/}
case "${#alldigits}" in
   4)
    if [ "${#allletters}" -gt 0 ];then
        echo "ok: 4 digits and letters: $var"
    else
        echo "Invalid: all numbers and exactly 4: $var"
    fi
    ;;
   *) echo "Invalid: $var";;
esac
查看更多
唯我独甜
5楼-- · 2019-07-19 16:08

If you don't mind using a little shell as well, you could do something like this:

echo "a1a1a1a1" |grep -o '[0-9]'|wc -l

which would display the number of digits found in the string. If you like, you could then test for a given number of matches:

max_match=4
[ "$(echo "a1da4a3aaa4a4" | grep -o '[0-9]'|wc -l)" -le $max_match ] || echo "too many digits."
查看更多
走好不送
6楼-- · 2019-07-19 16:09

I'm not sure about all the other input you might take (i.e. is ax12ax12ax12ax12 valid?), but this will work based on what you posted:

%> grep -P "^(?:\w\d){4}$" fileWithInput
查看更多
Evening l夕情丶
7楼-- · 2019-07-19 16:09

thanks for your answers finaly i wrote some script and it work perfect: . /P ab2b2 cd12 z9989 1ab26a9 1ab1c1 1234 24 a2b2c2d2

#!/bin/bash
echo "$@" |tr -s " " "\n"s >> sorting
cat sorting | while read tostr
do
  l=$(echo $tostr|tr -d "\n"|wc -c)
  temp=$(echo $tostr|tr -d a-z|tr -d "\n" | wc -c)

  if [ $temp -eq 4 ]; then
    if [ $l -gt 4 ]; then
      printf "%s " "$tostr"
    fi
  fi
done
echo
查看更多
登录 后发表回答