Bug in Safari Javascript?

Z

Zwerfkat

When running the code below, all browsers are showing "Hello World" except Safari which cannot match
the regular expression. See also http://www.testabc.nl/safari/test.html

When I change [^A]*? into .*? or add a space at the end of the string Safari is working alright
again.

I guess this is a bug in Safari Javascript, or?



<html>
<head>

<script language=JavaScript type=text/javascript>

var reg_date = /(Hello[^A]*?)\s*$/;
var str = 'Start: Hello world';

function show()
{

if(str.search(reg_date) != -1) alert(RegExp.$1);
else alert ("No match...");
}

</script>

</head>

<body>

<h3>Javascript code:</h3>
<div>var reg_date = /(Hello[^A]*?)\s*$/;</div>
<div>var str = 'Start: Hello world';</div>
<div>if(str.search(reg_date) != -1) alert(RegExp.$1);</div>
<div> else alert ("No match...");</div>

<p><button onclick="show();">start</button></p>
</body>
</html>
 
D

d d

Zwerfkat said:
When running the code below, all browsers are showing "Hello World" except Safari which cannot match
the regular expression. See also http://www.testabc.nl/safari/test.html
I guess this is a bug in Safari Javascript, or?

I also had a regular expression that worked in everything except Safari.
Don't worry though, Steve Jobs says it's the best browser in the world,
so it must be all the other browsers that are wrong.

It's garbage like Safari that means we have to sniff for browsers when
we really shouldn't need to.

I ended up having to do my replacements without regular expression. Oh,
and btw, my regular expression was about as easy as they get:

s=s.replace(/ /g,"_"); //replace spaces with underlines

~dd
 
R

RobG

Zwerfkat said:
When running the code below, all browsers are showing "Hello World" except Safari which cannot match
the regular expression. See also http://www.testabc.nl/safari/test.html

When I change [^A]*? into .*? or add a space at the end of the string Safari is working alright
again.

I guess this is a bug in Safari Javascript, or?



<html>
<head>

<script language=JavaScript type=text/javascript>

var reg_date = /(Hello[^A]*?)\s*$/;

I am no expert in regular expressions, however I think the use of ?
immediately after * is incorrect. It makes no sense to say one or more
repeats (?) of zero or more repeats ([^A]*).


If what you are after is a non-greedy version of a repeating pattern,
shift the ? outside the parenthesis and use:

/(Hello[^A]*)?\s*$/


which "works", or at least shows "Hello world" which is what you say
indicates "working".
 
R

RobG

d said:
Zwerfkat said:
When running the code below, all browsers are showing "Hello World"
except Safari which cannot match the regular expression. See also
http://www.testabc.nl/safari/test.html
I guess this is a bug in Safari Javascript, or?

I also had a regular expression that worked in everything except Safari.
Don't worry though, Steve Jobs says it's the best browser in the world,
so it must be all the other browsers that are wrong.
[...]

s=s.replace(/ /g,"_"); //replace spaces with underlines

In which version of Safari did that fail? It works in versions 2 and 3.
If you insist I'll test it in version 1, care to place a bet?
 
Z

Zwerfkat

I am no expert in regular expressions, however I think the use of ? immediately after * is
incorrect. It makes no sense to say one or more repeats (?) of zero or more repeats ([^A]*).

It makes perfectly sense. The "?" means non-greedy of the repeating pattern [^A]*.

/(Hello[^A]*?)\s*$/

This RegExp is eating as little as possible non 'A' characters (non-greedy) after "Hello" until the
space(s) are reached at the end of the line. So in this example the result is everything after
"Hello" without any space(s) at the end.
If what you are after is a non-greedy version of a repeating pattern, shift the ? outside the
parenthesis and use:

/(Hello[^A]*)?\s*$/

This is not what I am after. Moreover, the result will be "Hello world " including the space at the
end and that's not what I had in mind.
 
R

RobG

Zwerfkat said:
I am no expert in regular expressions, however I think the use of ? immediately after * is
incorrect. It makes no sense to say one or more repeats (?) of zero or more repeats ([^A]*).

It makes perfectly sense. The "?" means non-greedy of the repeating pattern [^A]*.

Non-greedy of zero or more seems to me it should be zero matches, and
since there is other stuff between Hello and the spaces at the end of
the string, there should be no matches - maybe Safari it the only one
getting it right:

"? directly following a quantifier makes the quantifier
non-greedy (makes it match minimum instead of maximum
of the interval defined).

"E.g: /(.)*?/ matches nothing or '' in all strings."

/(Hello[^A]*?)\s*$/

This RegExp is eating as little as possible non 'A' characters (non-greedy) after "Hello" until the
space(s) are reached at the end of the line. So in this example the result is everything after
"Hello" without any space(s) at the end.
If what you are after is a non-greedy version of a repeating pattern, shift the ? outside the
parenthesis and use:

/(Hello[^A]*)?\s*$/

This is not what I am after. Moreover, the result will be "Hello world " including the space at the
end and that's not what I had in mind.

Did you test that? I did. Neither Firefox, Safari or Opera include any
spaces after world - the ? is immediately before \s which seems to be
what you wanted. I haven't tested IE.
 
D

d d

RobG said:
In which version of Safari did that fail? It works in versions 2 and 3.
If you insist I'll test it in version 1, care to place a bet?

It was Safari 1.3 and the code that it was part of was dynamically
written into the parent page from inside an iframe using createElement.
I can well believe that in normal inline code it works fine.

~dd
 
R

ron.h.hall

Zwerfkat wrote:
If what you are after is a non-greedy version of a repeating pattern, shift the ? outside the
parenthesis and use:
/(Hello[^A]*)?\s*$/
This is not what I am after. Moreover, the result will be "Hello world " including the space at the
end and that's not what I had in mind.

Did you test that? I did. Neither Firefox, Safari or Opera include any
spaces after world - the ? is immediately before \s which seems to be
what you wanted. I haven't tested IE.

You may want to try your tests again.

The [^A]* allows the regular expression to take as many as possible of
anything other than "A", and that includes spaces. Since the "\s" is
quantified by "*", meaning none need to be found at the end,
processing of [^A]* can continue to the end of the string, and the
regular expression processing can return success, because the ?
quantifier allows (either zero or) one of these. So, in this case, any
trailing blanks should be found within RegExp.$1, where a right
trimmed string is desired.

There's another problem. Because you've introduced a zero or one test,
your expression will return success on a null string or a string that
is all blanks. It should fail if there is no "Hello" with zero or more
trailing blanks.

On the other hand, if [^A]*? is used, the processing will attempt to
succeed with the minimum taken by the [^A]'s. The first point at which
it will succeed is when there are zero or more blanks remaining,
because the \s* will cover (eat) all of those. Therefore, in the case
of the OP's regular expression, RegExp.$1 should not contain any
trailing blanks.
 
R

RobG

Zwerfkat wrote:
If what you are after is a non-greedy version of a repeating pattern, shift the ? outside the
parenthesis and use:
/(Hello[^A]*)?\s*$/
This is not what I am after. Moreover, the result will be "Hello world " including the space at the
end and that's not what I had in mind.
Did you test that? I did. Neither Firefox, Safari or Opera include any
spaces after world - the ? is immediately before \s which seems to be
what you wanted. I haven't tested IE.

You may want to try your tests again.

I can do them a thousand times, but computers being what they are,
given the same input and processing instructions they keep giving the
same result. :)

The next question is whether the tests were sufficient or not.

The [^A]* allows the regular expression to take as many as possible of
anything other than "A", and that includes spaces. Since the "\s" is
quantified by "*", meaning none need to be found at the end,
processing of [^A]* can continue to the end of the string, and the
regular expression processing can return success, because the ?
quantifier allows (either zero or) one of these. So, in this case, any
trailing blanks should be found within RegExp.$1, where a right
trimmed string is desired.

The OP's test case didn't inlcude any spaces at the end of the string,
I should have modified the test case but didn't.

There's another problem. Because you've introduced a zero or one test,
your expression will return success on a null string or a string that
is all blanks. It should fail if there is no "Hello" with zero or more
trailing blanks.
Yes.


On the other hand, if [^A]*? is used, the processing will attempt to
succeed with the minimum taken by the [^A]'s. The first point at which
it will succeed is when there are zero or more blanks remaining,
because the \s* will cover (eat) all of those. Therefore, in the case
of the OP's regular expression, RegExp.$1 should not contain any
trailing blanks.

Yes.
 
R

ron.h.hall

Zwerfkat wrote:
If what you are after is a non-greedy version of a repeating pattern, shift the ? outside the
parenthesis and use:
/(Hello[^A]*)?\s*$/
This is not what I am after. Moreover, the result will be "Hello world " including the space at the
end and that's not what I had in mind.
Did you test that? I did. Neither Firefox, Safari or Opera include any
spaces after world - the ? is immediately before \s which seems to be
what you wanted. I haven't tested IE.
You may want to try your tests again.

I can do them a thousand times, but computers being what they are,
given the same input and processing instructions they keep giving the
same result. :)
Even so, sometimes mistakes are made in reading test results,
especially when spaces are involved. But I see through your further
explanation, the problem was ... they weren't. ;-)
 
R

RobG

On Jul 11, 12:22 pm, (e-mail address removed) wrote:
Zwerfkat wrote:
<..>
If what you are after is a non-greedy version of a repeating pattern, shift the ? outside the
parenthesis and use:
/(Hello[^A]*)?\s*$/
This is not what I am after. Moreover, the result will be "Hello world " including the space at the
end and that's not what I had in mind.
Did you test that? I did. Neither Firefox, Safari or Opera include any
spaces after world - the ? is immediately before \s which seems to be
what you wanted. I haven't tested IE.
You may want to try your tests again.
I can do them a thousand times, but computers being what they are,
given the same input and processing instructions they keep giving the
same result. :)

Even so, sometimes mistakes are made in reading test results,
especially when spaces are involved. But I see through your further
explanation, the problem was ... they weren't. ;-)

Yes - GI, GI. :-x
 
D

d d

-Lost said:
It's probably a moot point, but that situation is the prime reason you
should use the RegExp constructor.

That might have worked for me. Too late now, my solution worked and is
already deployed. I was lucky that I wasn't trying to do a complex
regular expression.

~dd
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top