5

I had been working on a script and trying to understand it Here is a piece I could not understand.

grep -E "[a-z,A-Z,0-9\.\-]{2,}" /etc/hostname In this code I do understand that it tries to get data from /etc/hostname. Anything that starts with a-z or A-Z or numbers can be.

But, starting with:

\.\-]{2,}

this part I could not solve it. Can anyone explain whats that from?

  • I also did some tries and realised that when I play with {2,} coloring of the grep changes for example : {1,} makes the first part of the domain name red and dot and rest becomes normal color. and when I removed the "/./" part only dot becomes normal color but rest becomes red. red is the coloring from terminal for grep – Can Buyukburc Mar 25 '18 at 20:26
  • "Anything that starts with a-z or A-Z or numbers can be." No. If you want to mark the beginning of a string then you need ^. Without that the pattern can be anywhere in the string. – Hauke Laging Mar 25 '18 at 21:22
  • 1
    The sub-pattern will also match a comma – roaima Mar 25 '18 at 22:13
5

Here's what your regular expression means, from left to right:

[

start of a character set (or character class). It matches one character from the set.

a-z,A-Z,0-9

inside a character set means match any one character a-z or A-Z or 0-9. The commas are actually optional here, unless you're trying to literally match a comma.

\.\-

. is a special character that matches any character but inside a character set it has no special meaning and doesn't have to be escaped. The - here doesn't have to be escaped, if it's the first or last character in a set it matches a literal -, it only takes on special meaning when between two other characters in a set.

]

end of the character set. The set matches any one character a-z or A-Z or 0-9or . or -.

{2,}

is a quantifier. It means that the previous regex is to be matched 2 or more times.

So the command can be cut down to this:

grep -E "[a-zA-Z0-9.-]{2,}" /etc/hostname

When used with the -P flag grep interprets the pattern as a Perl regular expression. Perl regular expressions are nearly identical to Python regex. It's a more powerful mode than -E in my opinion. In Perl mode your command becomes:

grep -P "[a-zA-Z\d.-]{2,}" /etc/hostname
  • what should I look for so that I can understand the mentality or rule for the part {2,} – Can Buyukburc Mar 25 '18 at 23:55
  • The "mentality" of {2,} is that whoever wrote the line of code your'e asking about wanted to match [a-zA-Z0-9.-] two or more times. In other words he didn't want single character matches. If you want to learn about the "mentality or rule" of regular expressions in general pythex.org and the relevant Wiki pages are as good a start as any. – nagamani Mar 26 '18 at 3:55
  • 1
    You could also use [[:alnum:],.-] (if the comma is desired). – Benjamin W. Oct 30 '18 at 0:40
  • 1
    The set also matches commas and backslashes. – Kusalananda Jan 4 '19 at 9:33
0

The {2,} is a Quantifier, is this case it will match from 2 to as many as possible instances of the letters in the list between the [].

The \.\- will match a '-' or a '.'. These two characters are often special and often need to be escaped with the \. But in inside the group [], the dot is not special so the \ is not needed in that case. Additionally the - is a range indicator and is not special if it is the first or last in the group.

So, in the end you could use:

[,a-zA-Z0-9.-]{2,}
  • when I do {1,} ıt colors first part but writes the whole. When I do {,1} it again colors all of it. when I do {,} it again colors all of it – Can Buyukburc Mar 25 '18 at 20:40
  • 1
    Dot is not special inside []. – roaima Mar 25 '18 at 22:12
  • +1 ... and neither is dash, provided it is either the first or last character in the bracket range. Also probably worth noting that the the commas are literal as well and their repetition is unnecessary (in case the OP believes they are acting as range separators). – steeldriver Mar 25 '18 at 22:57
0

To understand, split it into parts:

  • grep

    Is the command being executed, read man grep for details.

  • -E

    Is calling the extended regex option of grep (equivalent to older egrep)

  • "

    Quoting is recommendable to avoid expansions/interpretations by the shell.

  • [

    Introduce a POSIX "bracket expression" (ends on the following ])

    A bracket expression (an expression enclosed in square brackets, "[]" ) is an RE that shall match a specific set of single characters.

  • a-z,A-Z,0-9.-

    The set of single characters to match, any in this list:

    abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,0123456789.-

    The \ is explicit in that list, it will be matched. Any character repeated acts as if only one has been listed, so the two , could be replaced by one ,. I believe that the \ was given by mistake. The user may believe that a (dot) . needs escaping (as it generally does in a regex, but not inside a "bracket expression". This range description (assuming a backslash is not meant to be matched) could be reduced to (keep the (dash) - as the last (or first) character):

    [a-zA-Z0-9.,-]
    

    Or (equivalently):

    [[:alnum:].,-]
    
  • {

    Introduce an "interval expression" (ends on the next }):

    … an interval expression of the format "{m}", "{m,}", or "{m,n}", … it shall match … repeated consecutive occurrences …

    So, the {2,} will match the count of: from 2 to any, or: two or more of the previous element.

  • /etc/hostname

    Inside the file /etc/hostname.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.