Translate Ruby regex into JavaScript - javascript

I've got such a regex in ruby on rails
/\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
I'd like to use same email validation logic in front end.
I've tried to use the .inspect method in the irb console, it doesn't seem to return a js valid regular expression.
As far as I understand \A is a ^, \Z is a $. [-a-z0-9] probably translates to [a-zA-Z0-9]. Not sure about the rest.
I've tried to look for an online converter too, couldn't find one. Answers in other similar topics in SO didn't work.
What's the easiest way to translate such regex from ruby into javascript?

As stated by Daniel in the comment it should just translate one to one, I incorrectly assumed that [-a-z0-9] should be replaced.
Ruby version:
/\A([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
JavaScript version:
/^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/
Some tests:
/^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i.test("test#email.com"); // true
/^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i.test("test#emailcom"); // false
/^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i.test("testemail.com"); // false

Did you try this?
class Regexp
def to_javascript
Regexp.new(inspect.sub('\\A','^').sub('\\Z','$').sub('\\z','$').sub(/^\//,'').sub(/\/[a-z]*$/,'').gsub(/\(\?#.+\)/, '').gsub(/\(\?-\w+:/,'('), self.options).inspect
end
end
When you render it to the client simply instantiate a new RegExp object with the resulting string:
new RegExp(regexpStringFromRuby);
Check the client_side_validations gem. It might be what you need.

Related

Regex expression for exactly known pattern without "cutting into" the string not working

I am currently developing a web-application where I work with java, javascript, html, jquery, etc. and at some point I need to check that whether an input matches a known pattern and only proceed if it is true.
The pattern should be [at least one but max 3 numbers between 0-9]/[exactly 4 numbers between 0-9], so the only acceptable variations should be like
1/2014 or 23/2015 or 123/2016.
and nothing else, and I CANNOT accept something like 1234/3012 or anything else, and this is my problem right here, it accepts everything in which it can find the above pattern, so like from 12345/6789 it accepts and saves 345/6789.
I am a total newbie with regex, so I checked out http://regexr.com and this is the code I have in my javascript:
$.validator.addMethod("hatarozat", function(value, element) {
return (this.optional(element) || /[0-9]{1,3}(?:\/)[0-9]{4}/i.test(value));
}, "Hibás határozat szám!");
So this is my regex: /[0-9]{1,3}(?:\/)[0-9]{4}/i
which I built up using the above website. What could be the problem, or how can I achived what I described? I tried /^[0-9]{1,3}(?:\/)[0-9]{4}$/ibut this doesn't seem to work, please anyone help me, I have everything else done and am getting pretty stressed over something looking so simple yet I cannot solve it. Thank you!
Your last regex with the anchors (^ and $) is a correct regex. What prevents your code from working is this.optional(element) ||. Since this is a static thing, and is probably true, so it does not show any error (as || is an OR condition, if the first is true, the whole returns true, the regex is not checked at all).
So, use
return /^[0-9]{1,3}\/[0-9]{4}$/.test(value);
Note you do not need the (?:...) with \/ as the grouping does not do anything important here and is just redundant. The anchors are important, since you want the whole string to match the pattern (and ^ anchors the regex at the start of the string and $ does that at the end of the string.)
You need use the the following special characters in your regex expression:
^ and $
or \b
so 2 regexp will be correct:
/\b[0-9]{1,3}(?:\/)[0-9]{4}\b/i;
or
/^[0-9]{1,3}(?:\/)[0-9]{4}$/i

Using javascript regex containing '#' in razor

I am performing email address validation with javascript in a razor view page.
The regex I am going to use is similar to the one proposed at Validate email address in JavaScript?
However, because the regex contains an '#' character, I am getting parser error when try to run the web app.
my regex looks like
/^...otherpart #* ... other part$/
I tried to add an '#' character to make the in the origin regex ... ##* ..., this eliminated the compilation error but seems to make the regex stops working. (we have used it in another web app that does not use razor engine, so I know it works).
Is there any other way to escape the '#' character?
You can add another # in front of it to escape ##, try leaving out the quantifer *. If this doesn't seem to work then add <text></text> around the function, it tells Razor to not parse the contents. Alternatively you can put Javascript in a separate file to accomplish your needs.
If for some reason you have multiple ## in your string, place code blocks ahead #:##
Put the following inside the regEx instead of #:
#('#')
The above will be rendered to a single #.
Your example will become:
/^...otherpart #('#')* ... other part$/
Simply just use double ##.
It works for me and I think that is the only way.
It's better to use #('#') instead of ## (not working for me).
Example
<input class="form-control" pattern="^[a-zA-Z#('#')]{5,20}$"/>

Partial Regexp Match in Javascript

I have a long regex that is generated to match URLs like
/^\/([^\/.?]+)(?:\/([^\/.?]+)(?:\/([^\/.?]+)(?:\.([^\/.?]+))?)?)?$/
Would match:
/foo/bar/1.html
as ['foo', 'bar', '1', 'html']
In Javascript I would like to get the parts that match as the user types the url (like a typeahead). For example if they typed:
/foo
It would tell me that /foo was matched, but the whole regexp hasn't been satisfied. Ruby can return an array with only the matching partial elements like : ['foo', nil, nil, nil] is this possible, or easy to do in Javascript?
#minitech basically gave half the answer: use ? after each group, and then you'll be able to match the regex even if they're missing. Once you can do that, then just check the groups of the regex result to see which bits have been matched and which haven't.
For example:
/^\/([^\/.?]+)?(?:\/([^\/.?]+)?(?:\/([^\/.?]+)?(?:\.([^\/.?]+))?)?)?$/.exec('/ab/c')
Would return:
["/ab:c", "ab:c", "c", undefined, undefined]
By checking and seeing that the fourth value returned is undefined, you could then figure out which chunks were/were not entered.
As a side note, if you're going to be working lots of regexs like this, you can easily lose your sanity just trying to keep track of which group is which. For this reason I strongly recommend using "named group" regular expressions. These are otherwise normal regular expressions that you can create if you use the XRegxp library (http://xregexp.com/), like so:
var result = XRegExp.exec('/ab/c', /^\/(?<fooPart>[^\/.?]+)?(?<barPart>?:\/([^\/.?]+)?(?:\/([^\/.?]+)?(?:\.([^\/.?]+))?)?)?$/)
var fooPart = result.fooPart
That library also has other handy features like comments that can similarly help keep regular expression under control. If you're only using this one regex it's probably overkill, but if you're doing lots of JS regexp work I can't recommend that library enough.

How to translate ruby regex to javascript? - (?i-mx:..) and Rails 3.0.3

Im using validates_format_of method to check email format:
validates_format_of :email, :with => /^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
also Im using livevalidation plugin to validate forms, so in my code Im getting:
(?i-mx:^([^#\\s]+)#((?:[-a-z0-9]+\\.)+[a-z]{2,})$)
Javascript cant read this regex. How or where I can change this regex to be as original:
/^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
?
Ruby and JavaScript regular expressions are parsed and executed by different engines with different capabilities. Because of this, Ruby and JavaScript regular expressions have small, subtle differences which are slightly incompatible. If you are mindful that they don't directly translate, you can still represent simple Ruby regular expressions in JavaScript.
Here's what client side validations does:
class Regexp
def to_javascript
Regexp.new(inspect.sub('\\A','^').sub('\\Z','$').sub('\\z','$').sub(/^\//,'').sub(/\/[a-z]*$/,'').gsub(/\(\?#.+\)/, '').gsub(/\(\?-\w+:/,'('), self.options).inspect
end
end
The recent addition of the routes inspector to rails takes a similar approach, perhaps even better as it avoids monkey patching:
def json_regexp(regexp)
str = regexp.inspect.
sub('\\A' , '^').
sub('\\Z' , '$').
sub('\\z' , '$').
sub(/^\// , '').
sub(/\/[a-z]*$/ , '').
gsub(/\(\?#.+\)/ , '').
gsub(/\(\?-\w+:/ , '(').
gsub(/\s/ , '')
Regexp.new(str).source
end
Then to insert these into your javascript code, use something like:
var regexp = #{/^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i.to_javascript};
The reason is that you are converting your regular expression using .to_s instead of .inspect. What you need to do in your view is use .inspect to get the proper format. Here is some sample code that should explain the issue:
email = /^([^#\s]+)#((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
email.to_s #"(?i-mx:^([^#\\s]+)#((?:[-a-z0-9]+\\.)+[a-z]{2,})$)"
email.inspect #"/^([^#\\s]+)#((?:[-a-z0-9]+\\.)+[a-z]{2,})$/i"
so, in your javascript view do something like this to get the actual string representation you want:
<%= email.inspect %>
I've written a small gem that translates Ruby regexes to JavaScript:
https://github.com/janosch-x/js_regex
It can handle more cases than the gsub approach, and includes warnings if any incompatibilities remain.
Note that, whatever you do, not all Ruby regexes can be fully translated to JS, because Ruby's regex engine has a lot of features that JavaScript's doesn't have.

Javascript Regular Expressions Lookbehind Failing

I am hoping that this will have a pretty quick and simple answer. I am using regular-expressions.info to help me get the right regular expression to turn URL-encoded, ISO-8859-1 pound sign ("%A3"), into a URL-encoded UTF-8 pound sign ("%C2%A3").
In other words I just want to swap %A3 with %C2%A3, when the %A3 is not already prefixed with %C2.
So I would have thought the following would work:
Regular Expression: (?!(\%C2))\%A3
Replace With: %C2%A3
But it doesn't and I can't figure out why!
I assume my syntax is just slightly wrong, but I can't figure it out! Any ideas?
FYI - I know that the following will work (and have used this as a workaround in the meantime), but really want to understand why the former doesn't work.
Regular Expression: ([^\%C2])\%A3
Replace With: $1%C2%A3
TIA!
Why not just replace ((%C2)?%A3) with %C2%A3, making the prefix an optional part of the match? It means that you're "replacing" text with itself even when it's already right, but I don't foresee a performance issue.
Unfortunately, the (?!) syntax is negative lookahead. To the best of my knowledge, JavaScript does not support negative lookbehind.
What you could do is go forward with the replacement anyway, and end up with %C2%C2%A3 strings, but these could easily be converted in a second pass to the desired %C2%A3.
You could replace
(^.?.?|(?!%C2)...)%A3
with
$1%C2%A3
I would suggest you use the functional form of Javascript String.replace (see the section "Specifying a function as a parameter"). This lets you put arbitrary logic, including state if necessary, into a regexp-matching session. For your case, I'd use a simpler regexp that matches a superset of what you want, then in the function call you can test whether it meets your exact criteria, and if it doesn't then just return the matched string as is.
The only problem with this approach is that if you have overlapping potential matches, you have the possibility of missing the second match, since there's no way to return a value to tell the replace() method that it isn't really a match after all.

Categories