Reputation: 326
I want to write a regular expression for accepting the following types in ruby -
1) "value1"
2) 'value2'
3) "" or ''
4) [{:this => :that, "that" => :this}, {'foo' => :bar}, {:bar => 'foo'}]
So far, I have the following -
regex = /(["']?)([^'"].*?[^'"])\1/
The problem with that is it does not accept the empty strings - "" and ''.
Can you suggest any alternative or improvement?
Upvotes: 0
Views: 271
Reputation: 51330
I don't know what regex flavor ruby uses, but assuming it's somewhat Perl-compatible:
regex = /(["'])(?:\\.|.)*?\1/
Demo: http://regex101.com/r/iP8hY8/1
This expression will allow you to escape quotes in your string "like \" that"
.
The trick here is to use an alternative in such a way that the second part of the alternative (the .
) will never be able to match a backslash. And the non-greedy quantifier ensures the backreference will match the ending quote first.
EDIT: Actually, I think I misread the 4th point in your question.
If you want the regex to match arrays of values, you'd have to create something more... parser-like, like this:
(?<value>
(?<string>(?<quote>["'])(?:\\.|.)*?\k<quote>|:\w+)
|
(?<hash>\{
(?:(?:(?<hashitem>\s*\g<string>\s*=>\s*\g<value>\s*),\s*)*\g<hashitem>
|\s*)
\})
|
\[
(?:(?:\s*\g<value>\s*,\s*)*\g<value>
|\s*)
\]
)
Demo: http://regex101.com/r/iP8hY8/2
This expression will actually mach arrays of strings too. Note that I didn't include anything for numbers since you don't mention them.
If you specifically want to only match arrays of hashes, then you can tweak the above expression a bit:
(?<value>
(?<string>(?<quote>["'])(?:\\.|.)*?\k<quote>|:\w+)
|
(?<hash>\{
(?:(?:(?<hashitem>\s*\g<string>\s*=>\s*\g<value>\s*),\s*)*\g<hashitem>
|\s*)
\})
|
\[
(?:(?:\s*\g<hash>\s*,\s*)*\g<hash>
|\s*)
\]
)
I'll let you further tweak this to your needs.
Upvotes: 1