Skip to content

Commit

Permalink
Merge branch 'master' of github.com:tom-lord/regexp-examples
Browse files Browse the repository at this point in the history
Conflicts:
	lib/regexp-examples/backreferences.rb
  • Loading branch information
Tom Lord committed Feb 22, 2015
2 parents eea8e9a + 96488ba commit 7471141
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 37 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Using any of the following will raise a RegexpExamples::IllegalSyntax exception:

* Lookarounds, e.g. `/foo(?=bar)/`, `/foo(?!bar)/`, `/(?<=foo)bar/`, `/(?<!foo)bar/`
* [Anchors](http://ruby-doc.org/core-2.2.0/Regexp.html#class-Regexp-label-Anchors) (`\b`, `\B`, `\G`, `^`, `\A`, `$`, `\z`, `\Z`), e.g. `/\bword\b/`, `/line1\n^line2/`
* However, a special case has been made to allow `^` and `\A` at the start of a pattern; and to allow `$`, `\z` and `\Z` at the end of pattern. In such cases, the characters are effectively just ignored.
* However, a special case has been made to allow `^`, `\A` and `\G` at the start of a pattern; and to allow `$`, `\z` and `\Z` at the end of pattern. In such cases, the characters are effectively just ignored.

(Note: Backreferences are not really "regular" either, but I got these to work with a bit of hackery!)

Expand Down
Binary file modified coverage/coverage-badge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions lib/regexp-examples/groups.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ def result
end
end

# Used as a workaround for when a grep is expected to be returned,
# but there are no results for the group.
# i.e. PlaceHolderGroup.new.result == '' == SingleCharGroup.new('').result
# (But using PlaceHolderGroup makes it clearer what the intention is!)
class PlaceHolderGroup
def result
[GroupResult.new('')]
end
end

class CharGroup
prepend GroupWithIgnoreCase
def initialize(chars, ignorecase)
Expand Down
38 changes: 21 additions & 17 deletions lib/regexp-examples/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,22 +44,22 @@ def parse_group(repeaters)
group = parse_or_group(repeaters)
when '\\'
group = parse_after_backslash_group
when '^', 'A'
when '^'
if @current_position == 0
group = parse_single_char_group('') # Ignore the "illegal" character
group = PlaceHolderGroup.new # Ignore the "illegal" character
else
raise IllegalSyntaxError, "Anchors cannot be supported, as they are not regular"
raise IllegalSyntaxError, "Anchors ('#{next_char}') cannot be supported, as they are not regular"
end
when '$', 'z', 'Z'
when '$'
if @current_position == (regexp_string.length - 1)
group = parse_single_char_group('') # Ignore the "illegal" character
group = PlaceHolderGroup.new # Ignore the "illegal" character
else
raise IllegalSyntaxError, "Anchors cannot be supported, as they are not regular"
raise IllegalSyntaxError, "Anchors ('#{next_char}') cannot be supported, as they are not regular"
end
when /[#\s]/
if @extended
parse_extended_whitespace
group = parse_single_char_group('') # Ignore the whitespace/comment
group = PlaceHolderGroup.new # Ignore the whitespace/comment
else
group = parse_single_char_group(next_char)
end
Expand Down Expand Up @@ -103,22 +103,26 @@ def parse_after_backslash_group
when rest_of_string =~ /\Ap\{([^}]+)\}/ # Named properties
@current_position += ($1.length + 2)
raise UnsupportedSyntaxError, "Named properties ({\\p#{$1}}) are not yet supported"
when rest_of_string =~ /\Ag/ # Subexpression call
when next_char == 'K' # Keep (special lookbehind that CAN be supported safely!)
group = PlaceHolderGroup.new
when next_char == 'R' # Linebreak
group = CharGroup.new(["\r\n", "\n", "\v", "\f", "\r"], @ignorecase) # A bit hacky...
when next_char == 'g' # Subexpression call
# TODO: Should this be IllegalSyntaxError ?
raise UnsupportedSyntaxError, "Subexpression calls (\g) are not yet supported"
when rest_of_string =~ /\A[GbB]/ # Anchors
raise IllegalSyntaxError, "Anchors cannot be supported, as they are not regular"
when rest_of_string =~ /\AA/ # Start of string
when next_char =~ /[bB]/ # Anchors
raise IllegalSyntaxError, "Anchors ('\\#{next_char}') cannot be supported, as they are not regular"
when next_char =~ /[AG]/ # Start of string
if @current_position == 1
group = parse_single_char_group('') # Ignore the "illegal" character
group = PlaceHolderGroup.new
else
raise IllegalSyntaxError, "Anchors cannot be supported, as they are not regular"
raise IllegalSyntaxError, "Anchors ('\\#{next_char}') cannot be supported, as they are not regular"
end
when rest_of_string =~ /\A[zZ]/ # End of string
when next_char =~ /[zZ]/ # End of string
if @current_position == (regexp_string.length - 1)
group = parse_single_char_group('') # Ignore the "illegal" character
group = PlaceHolderGroup.new
else
raise IllegalSyntaxError, "Anchors cannot be supported, as they are not regular"
raise IllegalSyntaxError, "Anchors ('\\#{next_char}') cannot be supported, as they are not regular"
end
else
group = parse_single_char_group( next_char )
Expand Down Expand Up @@ -182,7 +186,7 @@ def parse_multi_group
if next_char == ':' # e.g. /(?i:subexpr)/
@current_position += 1
else
return parse_single_char_group('')
return PlaceHolderGroup.new
end
when %w(! =).include?(match[2]) # e.g. /(?=lookahead)/, /(?!neglookahead)/
raise IllegalSyntaxError, "Lookaheads are not regular; cannot generate examples"
Expand Down
2 changes: 1 addition & 1 deletion lib/regexp-examples/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module RegexpExamples
VERSION = '0.5.2'
VERSION = '0.5.3'
end
28 changes: 10 additions & 18 deletions spec/regexp-examples_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,23 +103,15 @@ def self.examples_are_empty(*regexps)
end

context "for escaped characters" do
examples_exist_and_match(
/\w/,
/\W/,
/\s/,
/\S/,
/\d/,
/\D/,
/\h/,
/\H/,
/\t/,
/\n/,
/\f/,
/\a/,
/\v/,
/\e/,
/[\b]/
)
all_letters = Array('a'..'z') | Array('A'..'Z')
special_letters = %w(b c g p u x z A B C G M P Z)
valid_letters = all_letters - special_letters

valid_letters.each do |char|
backslash_char = "\\#{char}"
examples_exist_and_match( /#{backslash_char}/ )
end
examples_exist_and_match( /[\b]/ )
end

context "for backreferences" do
Expand Down Expand Up @@ -165,7 +157,6 @@ def self.examples_are_empty(*regexps)
/(?<!neglookbehind)/,
/\bword-boundary/,
/no\Bn-word-boundary/,
/\Glast-match/,
/start-of\A-string/,
/start-of^-line/,
/end-of\Z-string/,
Expand All @@ -177,6 +168,7 @@ def self.examples_are_empty(*regexps)
context "ignore start/end anchors if at start/end" do
examples_exist_and_match(
/\Astart/,
/\Glast-match/,
/^start/,
/end$/,
/end\z/,
Expand Down

0 comments on commit 7471141

Please sign in to comment.