Forum: Ruby Mark up patterns and escape all input?

960dbdfd730d53c6ea7ff4df072abe1c?d=identicon&s=25 Jack Bates (nottheoilrig)
on 2014-07-20 22:41
I want to replace e.g.
"ABCX^HXY^HYZ^HZDEF" with "ABC<b>XYZ</b>DEF"
"ABC_^HX_^HY_^HZDEF" with "ABC<u>XYZ</u>DEF"
and "&<>&^H&<^H<>^H>_^H&_^H<_^H>" with
"&amp;&lt;&gt;<b>&amp;&lt;&gt;</b><u>&amp;&lt;&gt;</u>"

In other words I want to wrap sequences of any character followed by
backspace followed by the same character with <b>, wrap sequences of
underscore followed by backspace followed by any character with <u>, and
escape all of the input.

How would you implement this in Ruby?

Here's how I implemented it in Python, but I'm struggling to port it
Ruby because Ruby's String.split() works differently than Python's
RegexObject.split()

> import cgi, re
>
> # Find sequences of X^HX (there can be whitespace in the middle of the
> # sequence) or _^HX (there can be vertical whitespace or underscores
> # in the middle of the sequence) where X is any character and ^H is
> # backspace
> parts = re.compile('((.)\b\\2(?:\s*(.)\b\\3)*)|(_\b.(?:[\n-\r_]*_\b.)*)',
re.UNICODE).split(input)
>
> # Escape all parts of the input and wrap sequences of X^HX in <b> and
> # sequences of _^HX in <u>
> parts[0::5] = map(cgi.escape, parts[0::5])
> parts[1::5] = (group and '<b>' + cgi.escape(re.compile('.\b').sub('', group)) +
'</b>' for group in parts[1::5])
> parts[4::5] = (group and '<u>' + cgi.escape(group.replace('_\b', '')) + '</u>'
for group in parts[4::5])
>
> print ''.join(parts[i] for i in range(len(parts)) if i % 5 in (0, 1, 4) and
parts[i])
B078cb4f4fb473c7a54d1fc36d10c70e?d=identicon&s=25 Regis d'Aubarede (raubarede)
on 2014-07-20 23:36
Jack Bates wrote in post #1153000:
> I want to replace e.g.
> "ABCX^HXY^HYZ^HZDEF" with "ABC<b>XYZ</b>DEF"
> "ABC_^HX_^HY_^HZDEF" with "ABC<u>XYZ</u>DEF"

Here, I replace ^H by 'a'  :
=============================
a="ABCXaXYaYZaZDEF"
class Array
 def chunk_cons()
  a=first
  nos=0
  each.chunk { |b|
    r=yield(a,b); a=b; nos+=1 unless r ;nos}.
   map {|(a,b)| b }
 end
end

p a.split(/(.a.)/).select {|a|a.size>0}.chunk_cons {|a,b|
   a+b=~/(.)a\1(.)a\2/}.
   map {|l|
    l.size==1 ? l.first : "<b>#{l.join('').gsub(/a./,'')}</b>"
   }.join('')
===============================
B078cb4f4fb473c7a54d1fc36d10c70e?d=identicon&s=25 Regis d'Aubarede (raubarede)
on 2014-07-21 00:00
Jack Bates wrote in post #1153000:
> I want to replace e.g.
> "ABCX^HXY^HYZ^HZDEF" with "ABC<b>XYZ</b>DEF"
> "ABC_^HX_^HY_^HZDEF" with "ABC<u>XYZ</u>DEF"


a="ABCXaXYaYZaZDAaAEF ABC_as_at_auDEF"
a="ABCXaXYaYZaZDAaAEF ABC_as_at_auDEF"

p a.gsub(/(.)a\1/) {|m| "<b>#{m[0]}</b>"}.gsub('</b><b>',"").
    gsub(/_a./) {|m| "<u>#{m[2]}</u>"}.gsub('</u><u>',"")


ABC<b>XYZ</b>D<b>A</b>EF ABC<u>stu</u>DEF"
960dbdfd730d53c6ea7ff4df072abe1c?d=identicon&s=25 Jack Bates (nottheoilrig)
on 2014-07-21 21:56
Thanks but I haven't managed to implement this with String.gsub()

> a = "&<>&a&<a<>a>_a&_a<_a>"
> p a.gsub(/(.)a\1/) {|m| "<b>#{m[0]}</b>"}.gsub('</b><b>',"").
>     gsub(/_a./) {|m| "<u>#{m[2]}</u>"}.gsub('</u><u>',"")
> => "&<><b>&<></b><u>&<></u>"

Whereas I need "&amp;&lt;&gt;<b>&amp;&lt;&gt;</b><u>&amp;&lt;&gt;</u>"
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.