In this lesson, we'll explore extended regular expression.
Now, in a previous lesson,
we mentioned how we can escape special characters and grep
but sometimes escaping turns a period operator into the regular period character.
Other times it works in reverse,
escaping a plus sign turns it from a regular plus sign into the plus sign operator.
So to avoid confusion, we can simply use extended regular expressions
which won't require us to remember what characters need to be escaped for,
to consider them for
regex operators.
Now we'll only need to escape characters when
we want them to turn from operators into
regular characters that we want to look for like a plus sign or a period.
We use extended red X by adding the dash E option to grep.
That's E with a capital letter.
Now to find all lines that contain the digit,
01 or more times we can use something like this or even easier.
We can use the equivalent
EGREP command
using EGREP is the same as typing grep dash E.
So you can make it a habit to always use EGREP instead of grep
to avoid mistakes where you might forget to escape a regex operator with a backslash
to find all strings that contain at least three zeros.
We can use the brackets operator
within, we specify two values separated by a comma.
The first value specifies the minimum amount
of repetitions for the previous element.
And the second value specifies the maximum amount of repetitions.
Now, in our case, we need to specify the minimum amount of three repetitions.
But since we don't want to place a limit on the maximum amount of repetitions,
we can omit the second value.
So our command looks like this
to find all strings that contain one, followed by most three zeros.
First of all, we add the first one into our search pattern,
then we follow that up with the zero digit
and add a regular expression. This time in reverse,
we omit to specify a minimum in the first field,
but we specify our maximum number of repetitions in the second field.
Not, this will also match ones followed by no zeros.
Since we didn't choose any specific minimum amount of repetitions.
And to find all strings that contain exactly three zeros,
we use the operator in a different way
instead of two fields with a minimum and a maximum,
we just place one value between our curly brackets.
Now the question mark character will let the
previous element exist precisely zero or one times.
And this basically makes it optional. It can exist once or not at all.
Now, let's say we're trying to find all text that says disabled or disable.
This means that the last D is optional so we can write an expression like this
in ree that this also matches the word disables.
This is a case where the letter D did not come at
the end and disable still matches because it's part of the word.
But just like before, we can add the dash W word option to grep to get rid of that.
So only disable or disabled specifically match if we'd want to match,
enabled or disabled, we could use the or operator.
This basically matches what it finds on its left side or its right side.
And we could combine this with our previous trick
where we made the last D letter optional to also find variations like enable,
enabled, disable disabled.
We'll also make the search case insensitive to also match variations
where the words have upper case letters in some spots.
Now it's time to see how we can put all this knowledge
to use and combine multiple regex operators to fine tune our searches.
But first, let's learn about ranges and sets.
Now, a range is specified in the form of
brackets A through Z.
Like here, this will match any one lowercase letter from AB CD, et cetera.
All the way to Z
and brackets zero through nine will match any one digit from 0 to 9.
And A set is specified in this form AB Z 954 will
match any one character specified with an AB Z 95 or four.
So to find all the strings that contain the text cat or cut,
we do something like this
with ranges and sets, we can make our searches both wide and specific.
Even at the same time.
For example, let's ask ourselves,
how would we find all config files that mention special device files that I have
with names like slash DEV slash SD A one or similar.
We could think like this, find all the strings that contain slash DEV slash,
followed by any random characters.
But this matches some weird stuff
dot asterisk is greedy matching
and it matches way too many things after it
captures the slash DEV part that we're looking for.
So we need to make our search wide enough to catch all the DEV device names,
but specific enough to only capture the parts we need.
Now, we can do this with ranges,
we can say after slash DEV match any number of lowercase letters from A to Z.
And as we learned, we can do that with the asterisk operator.
In this case, the asterisk operator will apply to the set specified before it
A through Z.
Now the output looks a little better, but we still see some things are missed
slash DEV slash TW A is matched instead of the entire slash DEV slash TW A zero.
How can we catch the digits at the end too
easy, we specify that a digit from 0 to 9 should exist there.
But now we run into another problem.
Only things that have a digit at the end are matched with this new red
X.
We'll only find slash DEV, slash SD A one but not slash DEV slash SD A.
This is an easy fix. Once again,
we just make the digit at the end optional with the question mark operator.
And this looks much better. Now,
now let's talk about subexpressions in math. We can see this.
Now, this is 1.6 equals seven.
That's because first multiplication will be done between two
and three and only after that the addition.
But what if we first wanna add one plus two and then multiply by three,
we would write this.
Now first,
the addition between one and two will
be done and only afterwards the multiplication,
this will be three times three, equaling nine
in Rx. We do a very similar thing.
Let's take a look at our last expression.
Now, if we scroll up in our output, we can see we still don't match everything we need.
Now, in this line P zero is left out. Why is that?
Because our expression after it finds slash DEV matches any number
of A to Z characters and then a digit at the end
and that's it. And that's where the match ends.
So in slash DEV slash TT Y zero P zero after that first zero is hit.
Our regex is happy with the partial result.
So how can we correct this?
We could tell it that after slash DEV, we have some letters and a digit at the end.
But after that, the same thing can repeat 012 or three or more times.
There can be other sequences of letters followed by a digit.
This way,
slash DEV slash TT Y zero would match first and then
P zero would be added to this match by that repetition.
So we basically want to say that this part of the regex
should look for this pattern,
existing 0123 or many more times so that it can match things like TT Y zero P zero.
Now what makes red X look for something that exists zero or more times
the asterisk operator.
But if we add it to the end, we get something like this
and this isn't as good as the star would apply to the previous element only.
And our asterisk would only be placed right after the question mark.
However, we want to apply our asterisk operator to our whole construct here.
Again, easy solution.
We just wrap our construct in parentheses.
And this way asterisk will apply to our entire subexpression
wrapped in parentheses instead of the last element only.
Now, we can tell our expression to look for lowercase letters or uppercase
with the or operator.
But writing it like this would be a mistake because now
the asterisk operator would only apply to capital A through Z
and we need it to apply to our entire A through Z construct.
Once again,
we can wrap in parentheses and make it a subexpression
and fix this and we end up with this command.
Now, tt Ys zero matches
and if we would go on,
we could fix things like slash DEV slash term slash A not matching because
our regex stops when it encounters the next front slash and so on.
This is the kind of logic and fine tuning.
We would go through when fixing our regular expressions or
making them laser focused on what we need to find.
We saw sets are in the form of AB C 123
and ranges A through Z.
If we add a carrot operator in there, we can negate them
that tells
redex that the elements in this set of range should not exist at this position.
Now imagine we want to search for the text, HTTPS,
but we don't want to find links to websites
since a link is usually in the form of HTTPS colon sign, we can build a red X like this.
It's basically saying look for the HTTPS string,
but make sure it's not followed by a colon sign.
And we'd end up with this grep command
to find the string, HTTP
and not followed by the S letter or the colon character. We just negate the set
otherwise said we simply enumerate what we want to negate.
Now, up to this point, we use the set with only one or two characters.
But as mentioned, we can negate ranges as well.
For example, we could tell our pattern after a front slash.
There should not be any lowercase letter.
Now keep in mind for any pattern you're trying to match.
There are multiple regex solutions you may find
to get this right.
You should practice until you feel comfortable with regular expressions.
It's also worth noting that
regex is not limited to grep,
you can use regular expressions in a lot of programs that deal with search patterns.
For example, the said utility also supports regular expressions
if you want to try out different regular expressions and see their effects.
Websites like Reg exr.com can be very helpful.