admin管理员组文章数量:1296440
I recently switched to Rails 4 and the security requirements no longer seem to allow the use of regular expressions in the style of /^..$/. The error states that regular expressions should instead be written in the style of /\A..\z/. Making this change seems to resolve all of my server side validation issues, but unfortunately it also broke all of my client side validation in javascript.
A simple example. I want to validate a username to be letters, number, or periods.
The old regex looked like /^[0-9a-zA-Z.]+$/ and worked both server side (Rails 3.x) and client side
new RegExp( /^[0-9a-zA-Z.]+$/ ).test('myuser.name') = true
The new regex looks like /\A[0-9a-zA-Z.]+\z/ and works server side but fails client side
new RegExp( /\A[0-9a-zA-Z.]+\z/ ).test('myser.name') = false
So I'm clearly doing something wrong, but I can't seem to find any explanations. I checked that \A..\z are valid regex to make sure that its not some Rails-specific hack and it seems to be legit.
Any ideas?
I recently switched to Rails 4 and the security requirements no longer seem to allow the use of regular expressions in the style of /^..$/. The error states that regular expressions should instead be written in the style of /\A..\z/. Making this change seems to resolve all of my server side validation issues, but unfortunately it also broke all of my client side validation in javascript.
A simple example. I want to validate a username to be letters, number, or periods.
The old regex looked like /^[0-9a-zA-Z.]+$/ and worked both server side (Rails 3.x) and client side
new RegExp( /^[0-9a-zA-Z.]+$/ ).test('myuser.name') = true
The new regex looks like /\A[0-9a-zA-Z.]+\z/ and works server side but fails client side
new RegExp( /\A[0-9a-zA-Z.]+\z/ ).test('myser.name') = false
So I'm clearly doing something wrong, but I can't seem to find any explanations. I checked that \A..\z are valid regex to make sure that its not some Rails-specific hack and it seems to be legit.
Any ideas?
Share Improve this question asked Feb 14, 2014 at 17:53 R. YanchuleffR. Yanchuleff 3231 silver badge15 bronze badges 1- MDN Regular Expressions – epascarello Commented Feb 14, 2014 at 18:11
3 Answers
Reset to default 10JavaScript does not support \A
or \z
in its RegExp
.
Here's some raw data, first for JavaScript:
var a = "hello\nworld"
(/^world/).test(a) // false
(/^world/m).test(a) // true
(/hello$/).test(a) // false
(/hello$/m).test(a) // true
Next, for ruby:
a = "hello\nworld"
a.match(/^world/) # => #<MatchData "world">
a.match(/\Aworld/) # => nil
a.match(/hello$/) # => #<MatchData "hello">
a.match(/hello\z/) # => nil
From this, we see that ruby's \A
and \z
are equivalent to JavaScript's ^
and $
as long as you don't use the multiline m
modifier. If you are concerned about the input having multiple lines, you're simply going to have to translate your regular expressions between these two languages with respect to these matching characters.
(?<![\r\n])^
emulates\A
, match absolute string start.$(?![\r\n])
emulates\z
, match absolute string end. (source)(?=[\r\n]?$(?![\r\n]))
emulates\Z
, match string end (before final newline if present).
If all of your line endings are \n
, you can simplify the above to:
\A
:(?<!\n)^
\z
:$(?!\n)
\Z
:(?=\n?$(?!\n))
Note: JavaScript has always supported lookahead (used for \z
& \Z
emulation above), but lookbehind (used for \A
emulation above) support is newer, and still limited due to Safari / WebKit, see caniuse. and bugs.webkit for details. Node.js has had lookbehind support since v9.
As a workaround for \A\a \Z\z
lack of support, you can add a "sentinel" character (or characters) to the end of the input string.
Please, note that:
- the sentinel character(s) should be something which very low chances of being used in the input string.
- should not be used in sensitive stuff (such as user verification or something) since a workaround like this can be easily exploitable.
In this specific case, since only [0-9a-zA-Z.]
are allowed, something like ¨
or ~
is ok.
Example:
let inputString = 'myuser.name';
inputString = '¨0' + inputString + '¨1';
let result = new RegExp( /¨0[0-9a-zA-Z.]+(?=¨1)/ ).test(inputString);
inputString.replace(/^¨0/, '').replace(/¨1$/, '');
If you're worried that, for some reason, the input string might have the selected characters you're using, you can escape them.
本文标签: javascriptRegExp A z doesnt workbut thats what Rails 4 requiresStack Overflow
版权声明:本文标题:javascript - RegExp A z doesnt work, but thats what Rails 4 requires - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741637362a2389717.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论