regex dingbat dodge - single char as string to repeatable singlechar.

J

John

I have text that might have had a star character in the proprietary
orginating system. The character is used in ratings boxes: A three-
star movie, a four-star restaurant, etc.

By the time it's exported and available to me, it's represented by a
string: "<star>".

I want to suround consecutive stars with font coding and replace each
instance of the string with a single character that, in conjuction
with the font change, will eventually print as a star.

To set up this substitution, I change the strings back to a unique
character, one that I reckon would never occur in nature.

When I try to surround any repetitions of this invented character, I
instead match everything.

===

#!/usr/bin/perl -w
use strict;

my $text = "Cuisine: Urban deli<ep>";
$text .= "Overall: <star><star><star><star><1/2> (very good to
excellent)<ep>";
$text .= "Food: <star><star><star><star><1/2><ep>";

$text =~ s/\<star\>/_STAR_/ig; # uscores easier in regex than angle
brackets.
$text =~ s/_STAR_/\xbc/g; # change pseudocharacter to single
character
$text =~ s/(\xbc*)/_STARFONT_$1_ENDSTAR/g; #bracket groups in more
pseudocode

print $text;

====

If I limit the search to five consecutive stars, the match works as I
intended:

===

#!/usr/bin/perl -w
use strict;

my $text = "Cuisine: Urban deli<ep>";
$text .= "Overall: <star><star><star><star><1/2> (very good to
excellent)<ep>";
$text .= "Food: <star><star><star><star><1/2><ep>";

$text =~ s/\<star\>/_STAR_/ig; # uscores easier in regex than angle
brackets.
$text =~ s/_STAR_/\xbc/g; # change pseudocharacter to single
character
$text =~ s/(\xbc{1,5})/_STARFONT_$1_ENDSTAR/g; #bracket groups of
stars in more pseudocode

print $text;

===

So what am I missing when it comes to the first search?

Certainly, I am missing some superior technique for matching repeated
instances of such a string, so I am open to suggestions there.

John Campbell
Haddonfield, NJ 08033
 
J

John W. Krahn

John said:
I have text that might have had a star character in the proprietary
orginating system. The character is used in ratings boxes: A three-
star movie, a four-star restaurant, etc.

By the time it's exported and available to me, it's represented by a
string: "<star>".

I want to suround consecutive stars with font coding and replace each
instance of the string with a single character that, in conjuction
with the font change, will eventually print as a star.

To set up this substitution, I change the strings back to a unique
character, one that I reckon would never occur in nature.

When I try to surround any repetitions of this invented character, I
instead match everything.

===

#!/usr/bin/perl -w
use strict;

my $text = "Cuisine: Urban deli<ep>";
$text .= "Overall: <star><star><star><star><1/2> (very good to
excellent)<ep>";
$text .= "Food: <star><star><star><star><1/2><ep>";

$text =~ s/\<star\>/_STAR_/ig; # uscores easier in regex than angle
brackets.
$text =~ s/_STAR_/\xbc/g; # change pseudocharacter to single
character
$text =~ s/(\xbc*)/_STARFONT_$1_ENDSTAR/g; #bracket groups in more
pseudocode

print $text;

====

If I limit the search to five consecutive stars, the match works as I
intended:

===

#!/usr/bin/perl -w
use strict;

my $text = "Cuisine: Urban deli<ep>";
$text .= "Overall: <star><star><star><star><1/2> (very good to
excellent)<ep>";
$text .= "Food: <star><star><star><star><1/2><ep>";

$text =~ s/\<star\>/_STAR_/ig; # uscores easier in regex than angle
brackets.
$text =~ s/_STAR_/\xbc/g; # change pseudocharacter to single
character
$text =~ s/(\xbc{1,5})/_STARFONT_$1_ENDSTAR/g; #bracket groups of
stars in more pseudocode

print $text;

===

So what am I missing when it comes to the first search?

Certainly, I am missing some superior technique for matching repeated
instances of such a string, so I am open to suggestions there.

In the first regular expression you are matching '\xbc*' and in the
second you are matching '\xbc{1,5}'. The '*' modifier matches *zero* or
more times and there are *zero* '\xbc' characters everywhere in the
string. The second one has to match at least *one* character. Change
'\xbc*' to '\xbc+'.


John
 
J

John

John wrote:
 The '*' modifier matches *zero* or
more times and there are *zero* '\xbc' characters everywhere in the
string.  The second one has to match at least *one* character.  Change
'\xbc*' to '\xbc+'.

That does the trick. It ought to come in handy.

Just realized that this snippet prints what in some systems is an
unprintable character.
I just see questions marks. Hope I didn't cause any problems with that.
 
B

Ben Morrow

Quoth John said:
I have text that might have had a star character in the proprietary
orginating system. The character is used in ratings boxes: A three-
star movie, a four-star restaurant, etc.

By the time it's exported and available to me, it's represented by a
string: "<star>".

I want to suround consecutive stars with font coding and replace each
instance of the string with a single character that, in conjuction
with the font change, will eventually print as a star.

To set up this substitution, I change the strings back to a unique
character, one that I reckon would never occur in nature.

When I try to surround any repetitions of this invented character, I
instead match everything.

#!/usr/bin/perl -w

You want

use warnings;

rather than -w, nowadays.
use strict;

my $text = "Cuisine: Urban deli<ep>";
$text .= "Overall: <star><star><star><star><1/2> (very good to
excellent)<ep>";
$text .= "Food: <star><star><star><star><1/2><ep>";

$text =~ s/\<star\>/_STAR_/ig; # uscores easier in regex
than angle

No they're not. Angles don't need escaping inside regexen.
brackets.
$text =~ s/_STAR_/\xbc/g; # change pseudocharacter to single
character
$text =~ s/(\xbc*)/_STARFONT_$1_ENDSTAR/g; #bracket groups in more
pseudocode

I don't know what the point of that is, unless you have some intervening
code that processes char-by-char.

s/( (?: <star> )+ )/_STARFONT_$1_ENDSTAR/gx;

will work perfectly well. Notice the difference between () and (?: )
(capturing vs. grouping) and my use of /x to make the regex more
comprehensible. Needing + instead of * has already been covered :).

Ben
 

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

Forum statistics

Threads
474,209
Messages
2,571,086
Members
47,684
Latest member
Rashi Yadav

Latest Threads

Top