Difference between revisions of "Tutorial9: Regular Expressions"
(→INVESTIGATION 1: SIMPLE & COMPLEX REGULAR EXPRESSIONS) |
(→INVESTIGATION 1: SIMPLE & COMPLEX REGULAR EXPRESSIONS) |
||
Line 155: | Line 155: | ||
:Proceed to INVESTIGATION 2. | :Proceed to INVESTIGATION 2. | ||
− | + | <br> | |
=INVESTIGATION 2: EXTENDED REGULAR EXPRESSIONS = | =INVESTIGATION 2: EXTENDED REGULAR EXPRESSIONS = |
Revision as of 09:26, 28 February 2021
Contents
USING REGULAR EXPRESSIONS
Main Objectives of this Practice Tutorial
- Define the term Regular Expressions
- Explain the difference between Regular Expressions and Filename Expansion
- Explain the purpose of Literal (Simple) Regular Expressions
- Understand and use common symbols for Complex Regular Expressions and their purpose
- Understand and use command symbols for Extended Regular Expressions and their purpose
- List several Linux commands that can use regular expressions
Tutorial Reference Material
Course Notes |
Linux Command/Shortcut Reference |
YouTube Videos | ||
Course Notes:
|
Regular Expressions
|
Linux Commands | Brauer Instructional Videos: |
KEY CONCEPTS
A regular expression … is a sequence of characters that define a search pattern.
Usually such patterns are used by string searching algorithms for "find" or
"find and replace" operations on strings, or for input validation.
Reference: https://en.wikipedia.org/wiki/Regular_expression
Regular Expressions vs. Filename Expansion
In a previous tutorial, you learned that filename expansion symbols allow the Linux shell to expand filenames as arguments (referred to as “globbing”) for file management commands. This is very useful for managing multiple files sharing similar characteristics such as the same file extension.
Filename Expansion symbols are used to search, edit and manipulate text and are used with Linux file management commands such as ls, rm, mv, cp, cat, less, more, head, tail, sort, uniq, cut, tr, and wc.
A regular expression is a combination of two types of characters: literals and special characters.
In combination, these characters define a logical pattern. Strings of text can be compared to this pattern
to see if they fit the pattern defined by the expression.
Reference: https://www.whoishostingthis.com/resources/regex/
This usually refers to text that is contained inside a file or text as a result
of issuing Linux commands using a Linux pipeline command.
Literal (Simple) Regular Expressions
The simplest regular expression is a series of letters and numbers, possibly including white space (tabs or space characters), that have no special meaning. Such a regular expression consists of ``literals; that is, normal letters, which match only an identical letter in the data being searched.Although there are many Linux commands that use regular expressions, the grep command is a useful command to learn how to display matches of patterns of strings within text files.
For example:
grep Linux document.txt
When an editor searches for a literal regular expression, it can only score a ``hit if it finds exactly that sequence of characters in the data it is searching.
Reference: http://osr507doc.xinuos.com/en/OSUserG/_Literal_chars_in_regexps.html
Complex Regular Expressions
The problem with using literals or simple regular expressions is that only simple or general patterns are matched.
Complex Regular Expressions use symbols to help match text for more precise (complex) patterns.
The most common complex regular expression symbols are displayed below:
- Anchors: ^ , $
Match lines the begin (^) or end ($) with a pattern. - Single Character: .
Represents a single character that can be any type of character. - Character Class: [ ] , [^ ]
Represents a single character but with restrictions. - Zero or More Occurrence: *
Zero or more occurrences of previous character.
- Anchors: ^ , $
Examples of how to use these complex regular expressions with the grep command are displayed below:
Extended Regular Expressions
Extended Regular Expressions consist of additional special characters
to “extend” the capability of regular expressions. You must use the egrep or grep -E commands
in order to properly use extended regular expressions with the grep command.
- Repetition: {min,max}
Allows for more precise repetitions. Using braces, you can specify
the minimum and/or maximum number of repetitions.
- Repetition: {min,max}
- Grouping: ( )
Perhaps you want to search for repetition for a group of characters, a word, or a phase.
You can enclose them within brackets ( ) to specify a group.
- Grouping: ( )
- or Condition: |
Can be used with grouping to match a variety of character(s), words or phases.
The | symbol is used to separate the variety of character(s) within a group.
- or Condition: |
Examples of how to use these complex regular expressions with the egrep command are displayed below:
INVESTIGATION 1: SIMPLE & COMPLEX REGULAR EXPRESSIONS
In this section, you will learn how to use the grep command with simple and complex regular expressions
to help search for patterns contained in text files.
Perform the Following Steps:
- Login to your matrix account.
- Issue a Linux command to confirm you are located in your home directory.
The wget command is used to download files from the Internet to your shell.
This will be useful to download text files and data files that we will be using for this tutorial. - Issue the following linux Linux command to download a text file to your home directory:
wget https://ict.senecacollege.ca/~murray.saul/uli101/textfile1.txt - Issue the ls Linux command to confirm that the text file was downloaded.
- View the contents of the textfile1.txt file using the more command and quickly view the contents of this file.
Although there are several Linux commands that use regular expressions,
we will only be using the grep command for this investigation. - Issue the following Linux command to match the pattern "the" within textfile1.txt:
grep "the" textfile1.txt
Take a few moments to view the output and observe the matched pattern. - Now, issue the grep Linux command with the -i option to ignore case sensitively:
grep -i "the" textfile1.txt
What do you notice is different when issuing this command?
You will notice that the pattern "the" is matched including larger words like "them" and "their".
You can issue the grep command with the -w option to only match the pattern as a word. - Issue the following Linux command:
grep -w -i "the" textfile1.txt
You should now see only strings of text that match the word "the" (upper or lower case).
Matching literal or simple regular expressions can be useful, but are limited
in what they can assist with pattern matching. For example, you may want to
search for a pattern located at the beginning or end of the string.
There are other regular expression symbols that provide more precise pattern matches.
These special characters are known as complex and extended regular expressions symbols.
In this section, we will focus on complex regular expressions and then discuss
extended regular expressions in INVESTIGATION 2. - Issue the following Linux command:
grep -w -i "^the" textfile1.txt
The ^ symbol is referred to as an anchor. In this case, it only matches
the word "the" (both upper or lowercase) at the beginning of the string. - Issue the following Linux command:
grep -w -i "the$" textfile1.txt
The $ symbol is used to anchor patterns at the end of the string. - Issue the following Linux command to anchor the word "the"
simultaneously at the beginning and end of the string:
grep -w -i "^the$" textfile1.txt
What do you notice?
Anchoring patterns at both the beginning and ending of strings can greatly assist
for more precise search patterns.
We will now be demonstrate the power of anchoring
combined with other complex regular expressions symbols. - Issue the following Linux command to match strings that begin with 3 characters:
grep "^..." textfile1.txt
What do you notice? Can lines that contain less than 3 characters be displayed? - Issue the following Linux command to match strings that begin and end with 3 characters:
grep "^...$" textfile1.txt
What do you notice compared to the previous command? - Issue the following Linux command to match strings that begin with 3 digits:
grep "^[0-9][0-9][0-9]" textfile1.txt
What did you notice? - Issue the following Linux command to match strings that end with 3 uppercase letters:
grep "[A-Z][A-Z][A-Z]$" textfile1.txt
Did any lines match this pattern? - Issue the following Linux command to match strings that consist of only 3 digits:
grep "^[0-9][0-9][0-9]$" textfile1.txt
What did you notice? - Issue the following Linux command to match strings that consist of only 3 alphanumeric digits:
grep "^[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]$" textfile1.txt
What did you notice?
The "*" complex regular expression symbol is often confused with the filename expansion symbol.
In other words, it does NOT represent zero or more of any character, but zero or more occurrences
of the character that comes before the "*" symbol. - To demonstrate, issue the following Linux command to display zero or more occurrences of the letter "x":
grep "x*" textfile1.txt
You will most likely notice most lines of the file is displayed. - Let's issue a Linux command to display strings that contain more than one occurrence of the letter "x":
grep "xx*" textfile1.txt
Why did this work? because the pattern indicates one occurrence of the letter "x",
followed by zero or MORE occurrences of the next letter "x".
If you combine the complex regular expression symbols ".*" it will act like
zero or more occurrences of any character (i.e. like "*" did in filename expansion). - Issue the following Linux command to match strings begin and end with a number with nothing or anything inbetween:
grep "^[0-9].*[0-9]$" textfile1.txt
Using simultaneous anchors combined with the ".*" symbol(s) can help you to refine your search patterns of strings. - Issue the following Linux command to display strings that begin with a capital letter,
end with a number, and contains a capital X somewhere inbetween:
grep "^[A-Z].*X.*[0-9]$" textfile1.txt
Let's look at another series of examples involving searching for strings that only contain valid numbers.
We will use pipeline commands to both display stdout to the screen and save to files
for confirmation of running these pipeline commands when run a checking-script later in this investigation. - Issue the following Linux command to create the regexps directory: mkdir ~/regexps
- Change to the regexps directory and confirm that you have moved to this directory.
- First, issue the following Linux command to download another data file called numbers1.dat:
wget https://ict.senecacollege.ca/~murray.saul/uli101/numbers1.dat - View the contents of the numbers.dat file using the more command and quickly view the contents of this file.
You should notice valid and invalid numbers contained in this file. When finished, exit the more command. - Issue the following linux pipeline command to display only whole numbers (i.e. no + or - sign):
grep "^[0-9]*$" numbers1.dat | tee faulty.txt
You may have noticed that the command does not entirely work. You may notice an empty line
(which is NOT a whole number). This occurs since the * regular expression symbol represents
ZERO or MORE occurrences of a number. You can use an additional numeric character class
with the * regular expression symbol to search for one or more occurrences of a number. - Issue the following Linux pipeline command to display only whole numbers:
grep "^[0-9][0-9]*$" numbers1.dat | tee whole.txt
You should see that this now works. - Issue the following Linux pipeline command to display whole positive or negative integers:
grep "^[+-][0-9][0-9]*$" numbers1.dat | tee signed.txt
What did you notice? Positive and negative numbers display, not not unsigned numbers. - Issue the following Linux pipeline command to display only whole numbers (with or without a positive or negative sign):
grep "^[+-]*[0-9][0-9]*$" numbers1.dat | tee all.txt
Did this command work? - Issue the following command to check that you created those hard links:
bash /home/murray.saul/scripts/week9-check-1
If you encounter errors, then view the feedback to make corrections, and then re-run the checking script.
If you receive a congratulation message that there are no errors, then proceed with this tutorial.
- Although very useful, complex regular expressions do NOT entirely solve our problem of displaying only valid unsigned and signed numbers.
In the next investigation, you will learn how to use extended regular expressions that will completely solve this issue.
- Proceed to INVESTIGATION 2.
INVESTIGATION 2: EXTENDED REGULAR EXPRESSIONS
In this section, you will learn how to use extended regular expressions to help further refine your searches when using regular expressions.
Perform the Following Steps:
- Make certain that you are located in your ~/regexps directory on your Matrix account.
- Issue the following linux pipeline command to download another data file called numbers2.dat:
wget https://ict.senecacollege.ca/~murray.saul/uli101/numbers2.dat - View the contents of the numbers2.dat file using the more command and quickly view the contents of this file.
You should notice valid and more invalid numbers contained in this file. When finished, exit the more command. - Issue the following linux pipeline command to display only whole numbers (with or without a positive or negative sign):
grep "^[+-]*[0-9][0-9]*$" numbers2.dat
You should notice multiple + or - signs appear prior to some numbers.
This occurs since you are searching or one or MORE occurrences of a + or - sign.
Using extended regular expression symbols to specify minimum and maximum repetitions: {min,max} can solve that problem. - Issue the following linux pipeline command (using extended regular expression symbols)
to display only whole numbers (with or without a positive or negative sign):
grep "^[+-]{0.1}[0-9]{1,}$" numbers2.dat
NOTE: most likely, there were NO results. This is due to the fact that the grep command was NOT issued correctly to use extended regular expression symbols. You would need to issue either grep -E (or more simply) issue the egrep command. The egrep command works with all regular expression symbols, and should be used in the future instead of the older grep command. - Reissue the above pipeline command using egrep instead of grep:
egrep "^[+-]{0,1}[0-9]{1,}$" numbers2.dat | tee better-number1.txt
You should have noticed that the command worked correctly this time because you used the egrep command.
NOTE: In extended regular expressions, the ? symbol can be used to represent the {0,1} repetition symbols
and the + symbol can be used to represent the {1,} repetition symbols - Reissue the above pipeline command using egrep instead of grep:
egrep "^[+-]?[0-9]+$" numbers2.dat | tee better-number2.txt
You should have seen the same results, but the extended regular expression required less typing. - Issue the following linux pipeline command to display signed, unsigned, whole, and decimal numbers:
egrep "^[+-]{0,1}[0-9]{1,}[.]{0,1}[0-9]*$" numbers2.dat | tee better-number3.txt - Issue the following Linux command to check that you correctly issued
those Linux pipeline commands using the tee command to create those text files:
bash /home/murray.saul/scripts/week9-check-2
If you encounter errors, then view the feedback to make corrections, and then re-run the checking script.
If you receive a congratulation message that there are no errors, then proceed with this tutorial.
You can also use extended regular expression symbols for grouping.
For example, you can search for repetitions of GROUPS of characters (like a word)
as opposed to just a single character or a GROUP of numbers as opposed to a single digit. - Issue the following linux pipeline command to download another data file called words.dat:
wget https://ict.senecacollege.ca/~murray.saul/uli101/words.dat - View the contents of the numbers2.dat file using the more command and quickly view the contents of this file.
You should notice valid and more invalid numbers contained in this file. When finished, exit the more command. - Issue the following linux pipeline command to display two or more occurrences of the word "the":
egrep -i "(the){2,}" words.dat | tee word-search1.txt more
NOTE: You should NOT see any output due to the fact that a space should be included at the end of the word "the".
Usually words are separated by spaces; therefore, there were no matches since there were not occurrences
of "thethe" as opposed to "the the" (i.e. no space after repetition of the pattern). - Reissue the previous pipeline command including a space in brackets:
egrep -i "(the ){2,}" words.dat | tee word-search2.txt
The "|" (or) symbol can be used within the grouping symbols to allow matching of additional groups of characters.
Again, it is important to follow the character groupings with the space character - Issue the following linux pipeline command to search for 2 or more occurrences of the word "the" or the word "and":
egrep -i "(the |and ){2,}" words.dat | tee word-search3.txt - Issue the following Linux command to check that you correctly issued
those Linux pipeline commands using the tee command to create those text files:
bash /home/murray.saul/scripts/week9-check-3
If you encounter errors, then view the feedback to make corrections, and then re-run the checking script.
If you receive a congratulation message that there are no errors, then proceed with this tutorial.
- Proceed to INVESTIGATION 3
INVESTIGATION 3: OTHER COMMANDS THAT USE REGULAR EXPRESSIONS
In this section, you will see how regular expressions can be used with other Linux utilities other than grep or egrep.
Perform the Following Steps:
- Let's look at using regular expressions with the man command.
Issue the following linux command :
man ls - We want to search for an option that can sort the file listing.
Type the following regular expression below and press ENTER:
/sort
FYI: The grep and egrep linux commands contain the regular expressions within quotes,
but most other Linux commands specify regular expressions using forward slashes
(e.g. /regular expression/ or /regular expression). - Scroll throughout the man pages for the ls command to view matches for the pattern "sort"
(You can press SPACE or key combination alt-b to move forward and backwards one screen respectively). - Press the letter q to exit the man pages for ls.
- Let's use regular expressions with the more command.
Issue the following linux command to view the contents of the textfile1.txt (downloaded in a previous section):
more textfile1.txt - We want to search for a pattern uli101 within this text file.
Type the following regular expression and press ENTER:
/uli101
What did you notice? - Search for the next occurrence of the pattern uli101 by re-typing
the following regular expression and pressing ENTER:
/uli101
you should now see the second occurrence of this pattern within the text file. - Press the letter q to exit the more command.
- Let's learn how to perform a simple search and replace within the vi utility by using regular expressions.
Issue the following linux command to edit the textfile1.txt file:
vi textfile1.txt
Let's first perform a simple search within this text file. - Type the following and press ENTER:
/uli101
You should move to the first occurrence of the pattern: uli101.
Let's search for the uli101 pattern, but replace it in capitals (i.e ULI101).
In vi, in order to perform and command, you need to go into last line mode, and then issue a command to apply to the entire text file, followed by a regular expression to search for and a regular expression to replace (i.e. /search/replace/). - Type the following and press ENTER:
:%s/uli101/ULI101
You should have noticed that the first occurrence of uli101 has been changed to ULI101. - Navigate throughout the text file to see if the other occurrences have been replaced.
You should notice they haven't for the other two occurrences. In order to replace for ALL occurrences,
you need to add the letter g (meaning "global") at the end of the last forward slash (e.g /search/replace/g). - Making certain that you are command mode in vi, type the following and press ENTER:
:%s/uli101/ULI101/g - Navigate throughout the text file to confirm that ALL occurrences of uli101 have been replaced with ULI101.
- Save changes to your vi editing session and exit by typing the following and pressing ENTER:
:x
- After you complete the Review Questions sections to get additional practice, then work on your
online assignment 3.
LINUX PRACTICE QUESTIONS
The purpose of this section is to obtain extra practice to help with quizzes, your midterm, and your final exam.
REVIEW QUESTIONS: SIMPLE & COMPLEX REGULAR EXPRESSIONS
Here is a link to the MS Word Document of ALL of the questions displayed below but with extra room to answer on the document to simulate a quiz:
https://ict.senecacollege.ca/~murray.saul/uli101/uli101_command_practice_9a.docx
Your instructor may take-up these questions during class. It is up to the student to attend classes in order to obtain the answers to the following questions. Your instructor will NOT provide these answers in any other form (eg. e-mail, etc).
Part A: Display Results from Linux Commands using Simple & Complex Regular Expressions
Note the contents from the following tab-delimited file called ~murray.saul/uli101/cars:
Plym fury 77 73 2500 chevy nova 79 60 3000 ford mustang 65 45 10003 volvo gl 78 102 9850 ford ltd 83 15 10507 chevy nova 80 50 3503 fiat 600 65 115 450 honda accord 81 30 6000 ford thundbd 84 10 17000 toyota tercel 82 180 755 chevy impala 65 85 1553 ford bronco 83 25 9505
Write the results of each of the following Linux commands using regular expressions for the above-mentioned file.
1. grep plym ~murray.saul/uli101/cars
2. grep -i fury ~murray.saul/uli101/cars
3. grep “^[m-z]” ~murray.saul/uli101/cars
4. grep -i “^[m-z]” ~murray.saul/uli101/cars
5. grep “3$” ~murray.saul/uli101/cars
6. grep -i “c.*5$” ~murray.saul/uli101/cars
Part B: Writing Linux Commands Using Regular Expressions
Write a single Linux command to perform the specified tasks for each of the following questions.
7. Write a Linux command to display all lines in the file called ~/text.txt that contains the pattern:
the
8. Write a Linux command to display all lines in the file called ~/text.txt that contains the word:
the
9. Write a Linux command to display all lines in the file called ~/text.txt that begin with a number.
10. Write a Linux command to display all lines in the file called ~/text.txt that end with a letter
(either upper or lowercase).
11. Write a Linux command to display all lines in the file called ~/text.txt that begin and end with a number.
12. Write a Linux command to display all lines in the file called ~/text.txt that contains exactly 3 characters that can be anything.
13. Write a Linux command to display all lines in the file called ~/text.txt that contains exactly 3 numbers.
14. Write a Linux command to display all lines in the file called ~/text.txt that contains 1 or more “C” characters.
REVIEW QUESTIONS: REGULAR EXPRESSIONS (INCLUDING EXTENDED REGULAR EXPRESSIONS)
Here is a link to the MS Word Document of ALL of the questions displayed below but with extra room to answer on the document to simulate a quiz:
https://ict.senecacollege.ca/~murray.saul/uli101/uli101_command_practice_9b.docx
Your instructor may take-up these questions during class. It is up to the student to attend classes in order to obtain the answers to the following questions. Your instructor will NOT provide these answers in any other form (eg. e-mail, etc).
Part A: Display Results from Linux Commands using Regular Expressions
Note the contents from the following tab-delimited file called ~murray.saul/uli101/numbers.txt:
+123 ---34 +++++++++++17 -45 45p8 25.6 11
Write the results of each of the following Linux commands using regular expressions for the above-mentioned file.
1. grep "^[-+]" ~murray.saul/uli101/numbers.txt
2. grep "^[-+]*.[0-9]" ~murray.saul/uli101/numbers.txt
3. grep "^[+-]?[0-9]" ~murray.saul/uli101/numbers.txt
(Why?)
4. egrep "^[+-]?[0-9]" ~murray.saul/uli101/numbers.txt
5. egrep "^[+-]?[0-9]+$" ~murray.saul/uli101/numbers.txt
6. egrep "^[+-]?[0-9]+[.]?[0-9]+$" ~murray.saul/uli101/numbers.txt
Part B: Writing Linux Commands Using Regular Expressions
Write a single Linux command to perform the specified tasks for each of the following questions.
7. Write a Linux command to display all lines in the file called ~/data.txt that begins with 1 or more occurrences of an UPPERCASE letter.
8. Write a Linux command to display all lines in the file called ~/data.txt that ends with 3 or more occurrences of the number 6
9. Write a Linux command to display all lines in the file called ~/data.txt that begins with 2 or more occurrences of the word “the” (upper or lower case).
10. Write a Linux command to display all lines in the file called ~/data.txt that begins with 2 or more occurrences
of the word “the” or the word “but” (upper or lower case).
11. Write a Linux command to display all lines in the file called ~/data.txt that begins with a minimum of 2 occurrences
and a maximum of 4 occurrences of the word “the” or the word “but” (upper or lower case).