JavaScript Equivalent of Ruby's String#Scan

JavaScript equivalent of Ruby's String#scan

String.prototype.scan = function (re) {
if (!re.global) throw "ducks";
var s = this;
var m, r = [];
while (m = re.exec(s)) {
m.shift();
r.push(m);
}
return r;
};

Converting Ruby regex to JavaScript one

In JavaScript you could do the following:

var re = new RegExp("<br /><a href=(.*?)>([0-9]+:[0-9]+)</a> <a href='.*?' target=_blank>(.*?)(?=</a><br><p.*?</p><br /><a href=.*?>([0-9]+:[0-9]+)</a> <a href='.*?' target=_blank>.*?</a>.*?<br />)", "m");

But this likely will not work the same because the m modifier in Ruby makes the . match all characters while in JavaScript this means multi-line mode where ^ and $ match at the start and end of each line.

So if you really think you need regex to do this and the HTML data you are matching has or could have line breaks, you will need to remove the m flag and replace .*? with a workaround such as [\S\s]*? to match those characters as well since JavaScript does not have a dotall mode modifier that works like the Ruby m modifier.

Ruby String#scan equivalent to return MatchData

You could easily build your own by exploiting MatchData#end and the pos parameter of String#match. Something like this:

def matches(s, re)
start_at = 0
matches = [ ]
while(m = s.match(re, start_at))
matches.push(m)
start_at = m.end(0)
end
matches
end

And then:

>> matches("foo _bar_ _baz_ hashbang", /_[^_]+_/)
=> [#<MatchData "_bar_">, #<MatchData "_baz_">]
>> matches("_a_b_c_", /_[^_]+_/)
=> [#<MatchData "_a_">, #<MatchData "_c_">]
>> matches("_a_b_c_", /_([^_]+)_/)
=> [#<MatchData "_a_" 1:"a">, #<MatchData "_c_" 1:"c">]
>> matches("pancakes", /_[^_]+_/)
=> []

You could monkey patch that into String if you really wanted to.

Is there a function like String#scan, but returning array of MatchDatas?

If you just need to iterate over the MatchData objects you can use Regexp.last_match in the scan-block, like:

string.scan(regex) do
match_data = Regexp.last_match
do_something_with(match_data)
end

If you really need an array, you can use:

require 'enumerator' # Only needed for ruby 1.8.6
string.enum_for(:scan, regex).map { Regexp.last_match }

How to pull a number out of a string in JavaScript?

You only need to use the new RegExp() part when creating dynamic regular expressions. You can use literals at other times. /\d+/ is the equivalent of new RegExp("\\d+"). Note that you have to escape special characters when using the latter.

Also noteworthy is that String#match returns null or an array. This is not apparent based on the supplied solutions (parseInt(name.match(/\d+/), 10)). It just so happens that it is converted to a string when passed to parseInt. ParseInt converts string values to integers (when possible).

name.match(/\d+/)[0]
/\d+/.exec(name)[0]

Those two are functionally identical in this case.

The other match you were referring to (the negative matching) requires a special flag. To duplicate the functionality of gsub you need to tell the regex to be applied more than once with the g flag.

'users[107][teacher_type]'.replace(/users\[|\]\[teacher_type\]/g,'')

Or if you had to use new RegExp for some reason you'd accomplish the same as above like so:

'users[107][teacher_type]'.replace(new RegExp('users\[|\]\[teacher_type\]', 'g'),'')

Notice again how I had to escape all the backslashes. Mozilla's Developer Center is a good reference to familiarize yourself with regex in javascript.

String::scan with string argument behave strange

With string '.', it scans for literal dots:

'foo'.scan '.'
# => []
'fo.o'.scan '.'
# => ["."]

While with regular expression /./, it matches any characters (except newline):

'foo'.scan /./
# => ["f", "o", "o"]
"foo\nbar".scan /./
# => ["f", "o", "o", "b", "a", "r"]

Is there a Perl equivalent for String.scan found in Ruby?

This does essentially the same thing.

my @elem = "foo bar baz" =~ /(\w+)/g

You can also set the "default scalar" variable $_.

$_ = "foo bar baz";
my @elem = /(\w+)/g;

See perldoc perlre for more information.


If you only want to use that string as an array, you could use qw().

my @elem = qw"foo bar baz";

See perldoc perlop ​ ​( Quote and Quote-like Operators ).

Is there a Perl equivalent for String.scan found in Ruby?

This does essentially the same thing.

my @elem = "foo bar baz" =~ /(\w+)/g

You can also set the "default scalar" variable $_.

$_ = "foo bar baz";
my @elem = /(\w+)/g;

See perldoc perlre for more information.


If you only want to use that string as an array, you could use qw().

my @elem = qw"foo bar baz";

See perldoc perlop ​ ​( Quote and Quote-like Operators ).



Related Topics



Leave a reply



Submit