Link to home
Start Free TrialLog in
Avatar of tel2
tel2Flag for New Zealand

asked on

Perl / HTML quoting problem

Hi Experts,

I've written some Perl code to write HTML and have run into a bit of a problem regarding quotes in the data.  To simplify the problem, I've got this kind of thing:
    $note = "Joe's cat \"should\" be OK";
    print "<input type='text' name='note' value='$note'>";
The result in the browser is, the value "Joe" appears as the value in the field.  This seems to be because I'm using single quotes around '$note' in the value attribute, and if I change them to double quotes (which will need to be escaped), I'll end up with "Joe's cat " for a similar reason.

How do I get values, which could contain single and/or double quotes, to appear as values in <input> tags?

Thanks.
Avatar of Bernard Savonet
Bernard Savonet
Flag of France image

B-) As you have experienced, you cannot solve this problem in a single string assigment... so split the string into pieces that you glue with dots

    $note = "Joe's cat \"should\" be OK";
    print "<input type='text' name='note' value='" . $note. "'>";
the first '" is ' then ", then "' is " then '
ASKER CERTIFIED SOLUTION
Avatar of sjklein42
sjklein42
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Best, it is always safe to HTML-quote both kinds of quotes, like this:

  $note = "Joe's cat \"should\" be OK";

  $note =~ s/\'/&#39;/g;	# HTML quote apostrophes
  $note =~ s/\"/&#34;/g;	# HTML quote double-quotes

  print "<input type='text' name='note' value='" . $note. "'>";
  

Open in new window

Avatar of tel2

ASKER

Hi fibo,

I tried your solution, but I got the same result, i.e.: "Joe" (without the quotes).


Hi sjklein42,

I think you're onto it, thank you!  I tried that and my tests work so far.
One minor question this raises for me is, even with my original print statement syntax, your solution still works, so is there any good reason why I should write:
    print "<input type='text' name='note' value='" . $note. "'>";
instead of my simpler and more concise:
    print "<input type='text' name='note' value='$note'>";
?
If the answer is: "it's just personal preference", then I've got to ask: "why would anyone prefer the more complex one?".
?
Avatar of tel2

ASKER

PS: If I'm gonna have to do this with all variables which are displayed in this way, is there a tidier way (e.g. some feature of the CGI module or something), or should I just write a little sub to do it for me?

BTW, for user friendliness, I plan to use this kind of syntax:
    $note =~ s/\'/&apos;/g;
    $note =~ s/\"/&quot;/g;
Thanks for the tip about "&quot;" in your first post, sjklein42.
My personal preference is to write a little subroutine so I have control over what it does and for improved code transparency.  But I'm not a big package fan.

There is no particular bias to using single or double quotes for the outer quotes.

sub HtmlQuote
{
    my $x = shift(@_);

    $x =~ s/\'/&#39;/g;	# HTML quote apostrophes
    $x =~ s/\"/&#34;/g;	# HTML quote double-quotes

    return $x;
} 

Open in new window

Do not use &apos;

It is not standard.

&quot; is ok

http://www.webmasterworld.com/forum119/430.htm
Avatar of tel2

ASKER

Thanks sjklein42,

I can't say I'm a big package fan either, but I do have the CGI package loaded, and just wondered if there was something in it which would handle these things for me (a little trick I picked up in "Lazy School", AKA "Code Reusing School").

There is no particular bias to using single or double quotes for the outer quotes.
Are you talking about:
    print "<input type='text' name='note' value='" . $note. "'>";
vs.
    print "<input type='text' name='note' value='$note'>";
?
The above both have double quotes as the outer quotes.  I was just wondering why/where someone would want to use the first syntax.
In Perl, I'd rather use double quotes for outer quotes, because if single quotes are the outer quotes then variables like $note will not be interpolated.

When you say "&apos;" is not standard, does that mean that some browsers will not understand it?  If not, where will it be a problem?

Thanks for the subroutine.  I assume you would then run it for each variable like this?
    $a = HtmlQuote($a);
    $b = HtmlQuote($b);
    $c = HtmlQuote($c);

Here's how I plan to do it:
    sub HtmlQuote
    {
        while ($varname = shift @_)
        {
            $$varname =~ s/\'/&#39;/g; # HTML quote apostrophes;
            $$varname =~ s/\"/&#34;/g; # HTML quote apostrophes;
        }
    }
Then call that in a single line listing all variables, like this:
    HtmlQuote(qw(a b c));
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Just a comment about the 1st vs 2nd formula
- you would use the 1st if the variable has any ' or " inside
- note however that although this works, as sjklein remarks the string thus created will not be OK for HTML

- so, in that case it is not useful, but it might be in other circumstances, eg creating a string mixing ' and "
Hi.

When I was talking about "no bias" I meant in the final HTML.   <input value="abc"> means the same as <input value='abc'>.   As I'm sure you know.

That's an interesting way to use the HTMLQuote subroutine to do a list of variables at once.

I was thinking more in the line of this:

print "<input type='text' name='note' value='" . HtmlQuote($note). "'>";

Open in new window

And yes, &apos; is not recognized in all browsers.  At least in 2006 that was true.  Maybe by now it is common usage but it is still not in the standard.  I just use the number style and play it safe.
Avatar of tel2

ASKER

Hi Tintin,
Thanks for those tips on escaping.
Yes, I find that here document syntax useful when printing several lines.
Regarding this syntax:
    print qq[<input type="text" name="note" value="$note">];
why would you prefer that to the simpler:
    print "<input type='text' name='note' value='$note'>";
?

Hi fibo,
Sorry - I still don't see the need.  Check this example out:
    $note = "Joe's cat \"should\" be OK";
    print "The note is '$note'";
Here's the output:
    The note is 'Joe's cat "should" be OK'
Worked fine, and it contains both types of quotes.  So, why are you saying I should do this:
    print "The note is '" . $note . "'";
?

Hi sjklein42,
OK - I'm with you now.  And that syntax also doesn't change the actual contents of the variable, which could be useful in some circumstances.
Avatar of Tintin
Tintin

Generally, I find it easier to use q and qq whenever there is mixed quotes.

I'm sure you'll agree that

$note = q[Joe's cat "should" be OK"];

Open in new window


is clearer and easier to write than

$note = "Joe's cat \"should\" be OK";

Open in new window



All comes down to preference and what you think looks better.

Avatar of tel2

ASKER

Sounds reasonable in that example, Tintin, but I'm talking about this example:
    print qq[<input type="text" name="note" value="$note">];
vs.
    print "<input type='text' name='note' value='$note'>";
Well, the example you give Joe's cat is a constant, ie you know the value and you know which ' and " you have inside.

But if it is a variable, you do not know if there are ' or ", how many, etc.. Then the 2 formulas do not lead to the same result.

I am not Perl-fluent... in PHP ' and " would lead to very different behavior
Avatar of tel2

ASKER

Hi fibo,

Sorry - I still don't get it.  Please give me an example where my 'print' syntax would fail.

Thanks.
tel2

there's not much difference in using

print qq[<input type="text" name="note" value="$note">];

Open in new window


or

print "<input type='text' name='note' value='$note'>";

Open in new window


Comes down to preference and whether you want the HTML attributes to have double quotes around them.
Tintin::  There is a huge difference between your two examples.

In the first example, variable interpolation (expansion) is not done and $note is not expanded.

In the second example, since you use double-quotes, $note IS expanded.

If you had used single quotes for the outer quotes in your second example, $note would not have been expanded.

Variable interpolation is done only when you use double quotes.

$ cat a
use CGI ':standard';
$note = escapeHTML(q[Joe's cat "should" be OK"]);
print qq[<input type="text" name="note" value="$note">\n];
print "<input type='text' name='note' value='$note'>\n";

Open in new window


$ perl a
<input type="text" name="note" value="Joe&#39;s cat &quot;should&quot; be OK&quot;">
<input type='text' name='note' value='Joe&#39;s cat &quot;should&quot; be OK&quot;'>

Open in new window

@Tintin - You're right.  Of course the "qq" form is the same as double-quote and the single "q" is the same as single-quote.  Sorry.
Avatar of tel2

ASKER

Hi fibo,

Did you see my last question to you, above?

But if it is a variable, you do not know if there are ' or ", how many, etc.. Then the 2 formulas do not lead to the same result.
Could you please prove your statement above, by supplying an example which makes the following print statement fail:
    print "The note is '" . $note . "'";

If you can't provide one, then I will assume your claim was an error, and will close this question, allocating the points to the other experts.

Thanks.
Personal note:
Hi tel2,

B-)
 I feel your wording as slightly aggressive, which I am sure is not your intention
End of personal note



1 - No problem with closing the question with nothing for me as my solution is really incomplete, since although Javascript would correctly generate the values, these would not be correct HTML:  I am claiming nothing!
As a matter of fact I had already considered that sjklein answer was excellent and voted "yes" to EE's question "was this comment helpful?"

2 - Tintin has said
Are you talking about:
    print "<input type='text' name='note' value='" . $note. "'>";
vs.
    print "<input type='text' name='note' value='$note'>";
?
The above both have double quotes as the outer quotes.  I was just wondering why/where someone would want to use the first syntax
.
My comment was just a side-answer to this wondering, saying that the first syntax should be preferred, since it would work with any content of $note. So I was preferring the expression
print "the note is'" . $note . "'";

Open in new window

you seem to agree with that, so not sure if any additional input is required from me.

The examples below show the point, if that was needed. Compare the 2 print versions for the 3 values:
that is true
that's true
that's "true"

Avatar of tel2

ASKER

Hi fibo,

Sorry if my requests came across as agressive.  I was getting a bit frustrated that you kept saying something which I could not understand the logic behind.  I had tried to prove my point with an example, but that example didn't satisfy you, and you hadn't provided any examples to prove your point.

Regarding your points 1 and 2.

1. I was planning to give you some points if you had proved your point, because that knowledge would have been useful to me, and I might have change the way I use 'print' in some cases, to the slightly less concise syntax.

2. Tintin didn't say that - I did.  Scroll up and you'll see it all.
My comment was just a side-answer...
I have no problem with side-answers (although I think you originally posted it as a main answer), but I have been trying to understand why/where it could be correct at all.

Thanks for the examples.  Here's a script which tests them using both print statements:

    #!/usr/bin/perl -l
    while ($note = <DATA>)
    {
            chomp $note;
            print "the note is '" . $note . "'";
            print "the note is '$note'";
            print;
    }
    __DATA__
    that is true
    that's true
    that's "true"

And here's the output:

    the note is 'that is true'
    the note is 'that is true'

    the note is 'that's true'
    the note is 'that's true'

    the note is 'that's "true"'
    the note is 'that's "true"'

What's the difference?
Avatar of tel2

ASKER

Having not heard anything further from fibo, I award points to sjklein42 & Tintin.  Thanks heaps!
Avatar of tel2

ASKER

PS: fibo,

I am not Perl-fluent... in PHP ' and " would lead to very different behavior

Well I'm not very PHP fluent, but here are your examples in PHP:

    $note1 = "that is true";
    $note2 = "that's true";
    $note3 = "that's \"true\"";

    print "the note is '" . $note1 . "'" . "\n";
    print "the note is '$note1'" . "\n\n";

    print "the note is '" . $note2 . "'" . "\n";
    print "the note is '$note2'" . "\n\n";

    print "the note is '" . $note3 . "'" . "\n";
    print "the note is '$note3'" . "\n\n";

And here's the output:

    the note is 'that is true'
    the note is 'that is true'

    the note is 'that's true'
    the note is 'that's true'

    the note is 'that's "true"'
    the note is 'that's "true"'

I don't see any problems there, and it looks the same as the Perl output to me.