Your problem is this:

sort {length $columnA <=> length $columnB}

That's not how sort works - it uses $a and $b to compare. Try instead:

sort {length $a <=> length $b}

Also - turn on use strict; use warnings; because this would have told you that:

Global symbol "$columnA" requires explicit package name (did you forge +t to declare "my $columnA"?)

The other gotcha is your use of \b - this is a word boundary, but it _doesn't_ match when you've got a symbol:

print "matches first" if "a (word) in context " =~ m/\b\(word\)\b/; print "matches second" if "a (word) in context " =~ m/\(word\)/;

First doesn't match, because space-to-bracket isn't a word boundary: A word boundary (\b ) is a spot between two characters that has a \w on one side of it and a \W on the other side of it (in either order), - both space and bracket are \W.

So you can't do it like that - either you've got to skip the word boundary element, decide how much you like whitespace, or use a lookaround. Or just don't worry about it and allow substring matching. Depends a bit on what data you've got to worry about something like:

print "matches third" if "a (word) in context " =~ m/(?<=\s)\(word\)(? +=\s)/;

Uses lookbehind/lookahead to detect spaces. (You might need to handle start/end of line too) - so a 'not word' negative assertion might be required instead:

print "matches fourth" if "a a in context (word) " =~ m/(?<!\w)\(word\ +)(?=\s|$)/;

This should match (word) as long as it isn't immediately preceeded by a alpha-numeric (so is ok with start of line, where (?<=\W) wouldn't be) and a trailing space or end-of-line. If your case is more complicated that that (e.g you need to _not_ match ((word) here) then this should at least give you a start point.

#!/usr/bin/env perl use strict; use warnings; use Data::Dumper; my %dic; while (<DATA>) { chomp; my($columnA, $columnB) = split("\t", $_); $dic{$columnA} = $columnB; } print Dumper \%dic; my $regex = join ( "|", map {quotemeta} sort { length $a <=> length $b + } keys %dic ); $regex = qr/(?<!\w)($regex)(?=\s|$)/; print $regex; my $sentence = "this word word (word) is a word\n"; $sentence =~ s/$regex/$dic{$1}/g; print $sentence; __DATA__ word word parola parola (word) (parola)

In reply to Re: Symbols in regex by Preceptor
in thread Symbols in regex by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.