0
const spaceRegex = /<mspace\s+.*?\/>/
const answer = '<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>h</mi><mfenced><mi>x<mspace linebreak="newline"/></mi></mfenced><mo>=</mo><semantics><mrow><mo>-</mo><mn>3</mn></mrow></semantics><mspace linebreak="newline"/><mi>D</mi><mo>=</mo><mi mathvariant="normal">&#x211D;</mi></math>'

I have a regex to match <mspace .... />, there are two matches in the above answer. I want to replace the last match with <mspace width="10px"/>

So I want the output to be,

'<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>h</mi><mfenced><mi>x<mspace linebreak="newline"/></mi></mfenced><mo>=</mo><semantics><mrow><mo>-</mo><mn>3</mn></mrow></semantics><mspace width="10px"/><mi>D</mi><mo>=</mo><mi mathvariant="normal">&#x211D;</mi></math>'
Henok Tesfaye
  • 8,287
  • 13
  • 47
  • 84
  • 1
    Just a heads up, you're using regex where it wasn't intended to be used; see https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/ – user229044 Jan 17 '20 at 18:00
  • 1
    [String.prototype.lastIndexOf()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/lastIndexOf) seems like it should do the job. – Andre Nuechter Jan 17 '20 at 18:02
  • Check this answer: https://stackoverflow.com/a/44568739/10905239 Reach me if you didnt understand it – Mehdi Babapour Jan 17 '20 at 18:02
  • 1
    Not a very elegant way, but you could do this `//`. This assumes that both occurrences exist in one single line. – revo Jan 17 '20 at 18:03

1 Answers1

0

Regex is not a right way to deal with XML.
The better one is using DOMParser and XMLSerializer so you can traverse the DOM and update elements using DOM methods:

const answer = '<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>h</mi><mfenced><mi>x<mspace linebreak="newline"/></mi></mfenced><mo>=</mo><semantics><mrow><mo>-</mo><mn>3</mn></mrow></semantics><mspace linebreak="newline"/><mi>D</mi><mo>=</mo><mi mathvariant="normal">&#x211D;</mi></math>';

const D = (new DOMParser()).parseFromString(answer, "text/xml")

const mspaces = D.getElementsByTagName('mspace');
mspaces[mspaces.length-1].outerHTML = '<mspace width="10px"/>';

const updated = (new XMLSerializer()).serializeToString(D);

console.log(updated)
.as-console-wrapper {top:0; max-height:none !important}

The regex solution is also available, but less reliable:

const answer = '<math xmlns="http://www.w3.org/1998/Math/MathML"><mi>h</mi><mfenced><mi>x<mspace linebreak="newline"/></mi></mfenced><mo>=</mo><semantics><mrow><mo>-</mo><mn>3</mn></mrow></semantics><mspace linebreak="newline"/><mi>D</mi><mo>=</mo><mi mathvariant="normal">&#x211D;</mi></math>';

const updated = answer.replace(/(.*)<mspace[^/]+\/>/, '$1<mspace width="10px"/>');

console.log(updated)
.as-console-wrapper {top:0; max-height:none !important}

Hope this helps.

Kosh
  • 16,966
  • 2
  • 19
  • 34