1

I have this string (html):

html = 'x<sub>i</sub> - y<sub>i)<sub>2</sub>' 

I would like to convert this html string to latex in a robust way. Let me explain:

  1. <sub>SOMETHING</sub> -> converted to _{SOMETHING}

I already know how to do that:

latex = re.sub(r'<sub>(.*?)</sub>',r'_{\1} ', html)
  1. Sometimes the first part <sub> or its closing tag is missing, like in the example string. In that case, the output should still be correct.

So how I was thinking of doing it is: After running 1, I take the string after <sub> and anything before </sub> with _{SOMETHING}

text = re.sub(r'<sub>(.*?)</sub>',r'_{\1} ', html)
print(text)
# if missing part:
text = re.sub(r'<sub>(.*?)',r'_{\1} ', text)
print(text)
latex  = re.sub(r'(.*?)</sub>',r'_{\1} ', text)

… but I get:

x_{i}  - y_{i)<sub>2} 
x_{i}  - y_{i)_{} 2} 
x_{i}  - y_{i)_{} 2} 

What I would like to get:

x_{i}  - y_{i})_{2}
6
  • 4
    Sounds like text = text.replace('<sub>', '_{').replace('</sub>', '}') should do. Commented Apr 12, 2019 at 22:27
  • @WiktorStribiżew Thanks for your comment. When I try your command I get: x_{i} - y_{i)_{2}. It's almost good, but there is a missing }bracket after the second i. Commented Apr 14, 2019 at 15:51
  • How can you describe the place where the } is missing? It is not possible without more detailed requirements. Commented Apr 14, 2019 at 17:38
  • @WiktorStribiżew That is very true. Sorry, yes, you are completely right. Commented Apr 14, 2019 at 17:40
  • 1
    My top comment solution is based on an assumption you have texts that are segmented into different parts, and the corresponding </sub> may reside in the next segment, so it should suffice to just replace them one by one separately (this is a very common scenario in localization). That means you do not need to make any guess work. If it is not your case, you should explain the tagged text format or context the text appears in, else, the "regular" language is of no help. Commented Apr 14, 2019 at 17:43

2 Answers 2

2

Assuming you have texts that are segmented into different parts, the corresponding <sub> / </sub> tags may reside in the adjoining segments, so it should suffice to just replace them one by one separately, and you do not need to make any guess work.

Just use

text = text.replace('<sub>', '_{').replace('</sub>', '}')

to replace each <sub> with _{ and </sub> with } in any context.

Sign up to request clarification or add additional context in comments.

Comments

1

You need to use greedy regexes (i.e. without ?) for the unmatched tags, otherwise you'll always get zero-width matches.

>>> text = '1<sub>2'
>>> re.sub(r'<sub>(.*)', r'_{\1} ', text)
'1_{2} '

BTW while figuring this out, I noticed you can put the second two regexes together like this:

re.sub(r'<sub>(.*)|(.*)</sub>', r'_{\1\2} ', text)

2 Comments

This does not seem to work. I get: _{x<sub>i</sub> - y<sub>i)<sub>2}
@henry Yes, you need to replace the matched tags first, then run my regex to replace the unmatched tags. But don't worry about it anymore, since Wiktor's answer is better for your case.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.