Daviz Castilla Daviz Castilla - 6 months ago 9
Ruby Question

Regex chain replacement issue

I try to develop a super basic template language, and I have a problem with RegEx, I try to convert this:

# Tilte
## Subtitle
### Subsubtitle
Lorem ipsum b(dolor) sit i(amet), consectetur u(adipisicing) elit


to this:

<h1>Title</h1>
<h2>Subtilte</h2>
<h3>Subsubtitle</h3>
Lorem ipsum <strong>dolor</strong> sit <i>amet</i>, consectetur <u>adipisicing</u> elit


But I get this:

<h1></h1>
<h2>TEma 4</h2>
<h3>Subtitle</h3>
Lorem ipsum <strong>Subsubtitle</strong> sit i(amet), consectetur u(adipisicing) elit


Here is my code:

input = ARGV[0]

regExes = {

h1: [/^# (.*)$/, "<h1>", "</h1>"],
h2: [/^## (.*)$/, "<h2>", "</h2>"],
h3: [/^### (.*)$/, "<h3>", "</h3>"],
b: [/b\((.*)\)/, "<strong>", "</strong>"],

}

strFile = File.read input

puts "\t", strFile

for index, regEx in regExes

actualNode = regExes[index]
print actualNode, "\n"
strFile.gsub! actualNode[0], "#{actualNode[1]}#{$1}#{actualNode[2]}"

end

puts strFile


What should I do?

Answer

You need to define the regexes in this order (and mind the lazy matching with strong, underline and bold tags and the word boundary \b in front of each of those to make sure we do not match parts of words):

regExes = {

    h3: [/^### (.*)$/, "<h3>", "</h3>"],
    h2: [/^## (.*)$/, "<h2>", "</h2>"],
    h1: [/^# (.*)$/, "<h1>", "</h1>"],
    b: [/\bb\((.*?)\)/, "<strong>", "</strong>"],
    i: [/\bi\((.*?)\)/, "<i>", "</i>"],
    u: [/\bu\((.*?)\)/, "<u>", "</u>"],
}

and then use a non-destructive gsub:

input = input.gsub(actualNode[0], "#{actualNode[1]}\\1#{actualNode[2]}")

See this IDEONE demo

Comments