-
-
Notifications
You must be signed in to change notification settings - Fork 399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace date-parser with log-parser (regular expressions) #1148
Conversation
Thank you for contributing to Based on the files changed in this PR, it would be good to pay attention to the following details when reviewing the PR:
Automated comment created by PR Commenter 🤖. |
## Out of scope | ||
|
||
- Teaching the syntax of regular expressions | ||
- Compiling Regular expressions with variable content |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to add some step that would require an interpolated regex with escaping a variable, but I couldn't come up with anything thematic that wouldn't be better done with String.starts_with?
:/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding a step to tag_with_user_name/1
?
Maybe something like bolding the user names whenever they are mentioned without "User"?
LogParser.tag_with_user_name("[INFO] User Alice created a new project.")
# => "[USER] Alice [INFO] User Alice created a new project"
LogParser.tag_with_user_name("[INFO] User Alice created a new project. Alice has a reputation of 643.")
# => "[USER] Alice [INFO] User Alice created a new project. **Alice** has a reputation of 643."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, I think it's definitely an improvement over the date-parser
.
I left a couple of small suggestions, but I'm already approving. Ping me on Slack if you need another round of review, I might miss the notification otherwise.
Here is my solution as reference
defmodule LogParser do
def valid_line?(line) do
regex = ~r/^\[(DEBUG|INFO|WARNING|ERROR)\]/
line =~ regex
end
def split_line(line) do
regex = ~r/<[~\*=-]*>/
String.split(line, regex)
end
def remove_artifacts(line) do
regex = ~r/end-of-line\d+/i
String.replace(line, regex, "")
end
def tag_with_user_name(line) do
regex = ~r/User\s+(\S+)/
case Regex.run(regex, line) do
[_user_name, name] -> "[USER] #{name} " <> line
_ -> line
end
end
end
|
||
_Anchors_ are used to tie the regular expression to the beginning or end of the string to be matched: | ||
If a simple boolean check is not enough, use the `Regex.run/3` function to get a list of all captures (or `nil` if there was no match). The first element in the returned list is always the whole string, and the following elements are matched groups. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add an example, something like
Regex.run(~r/test number (\d+)/, "This is test number 256")
# => ["test number 256", "256"]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: 394686e
(#1148)
It also made me realize that the initial description was wrong :) the first element isn't always the whole input string, only the part of it that was a match for the regex.
|
||
The `=~/2` operator is useful to perform a regex match on a string to return a `boolean` result. | ||
~~~~exercism/note | ||
This exercise assumes that you already know regular expression syntax, including character classes, quantifiers, groups, and captures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we offer a link or two for those who don't?
To be honest, I just googled learning regex and found plenty of material, but there are also a bunch of links in the hints we could reuse.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: a133b42
(#1148)
- Know that some String functions accept regular expressions, e.g. match?, replace, split. | ||
- Know about modifiers (e.g. unicode, case-insensitive) | ||
- Know how to get a value from a captured group | ||
- Know that sigils can be used with different delimiters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We mention this point in the intro, but we don't practice it in an exercise.
Maybe we could have one exercise that involves parsing several /
and ask them to use another delimiter for readability?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. It would also be possible to do an analyzer check for the delimiter because that information is kept in the AST:
iex(2)> quote do
...(2)> ~r()
...(2)> end
{:sigil_r, [delimiter: "(", context: Elixir, import: Kernel],
[{:<<>>, [], [""]}, []]}
## Out of scope | ||
|
||
- Teaching the syntax of regular expressions | ||
- Compiling Regular expressions with variable content |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about adding a step to tag_with_user_name/1
?
Maybe something like bolding the user names whenever they are mentioned without "User"?
LogParser.tag_with_user_name("[INFO] User Alice created a new project.")
# => "[USER] Alice [INFO] User Alice created a new project"
LogParser.tag_with_user_name("[INFO] User Alice created a new project. Alice has a reputation of 643.")
# => "[USER] Alice [INFO] User Alice created a new project. **Alice** has a reputation of 643."
I postponed the two improvement ideas (#1162) because I'm low on time and creativity at the moment, but I really want to get this out before the ExHort starts on 08.08. |
Closes #941