JSFiddle - React, Tailwind, and code Playground
by Nikolay Petrov
June 07, 2017
HTML
<p>This is a sentence. This is another sentence.</p>
<p>This +79500484063 sentence has <strong>emphasis</strong> inside it.</p>
<p>79251491035</p>
<p>9251491035</p>
<p>7925-1491035</p>
<p><span>This sentence spans</span><span> two elements.</span></p>
CSS
.sentence {
text-decoration: underline wavy red;
}
.sentence-end {
border-right: 1px solid red;
}
JavaScript
function parseText( element ){
var stack = [ element ];
var group = false;
//var re = /(?!\s|$).*?(\.|$)/;
var re = /\+{0,1}(8{0,1}|7{0,1}){0,1} {0,1}(\([0-9]{3,4}\)|\d{3,4}){0,1} {0,1}-{0,1}\d{3}-{0,1}\d{0,2}-{0,1}\d{0,2}/g;
while ( stack.length > 0 ){
var node = stack.shift();
if ( node.nodeType === Node.TEXT_NODE )
{
if ( node.textContent.trim() != "" )
{
var match;
while( node && (match = re.exec( node.textContent )) )
{
var start = group ? 0 : match.index;
var length = match[0].length + match.index - start;
if ( start > 0 )
{
node = node.splitText( start );
}
var wrapper = document.createElement( 'span' );
var next = null;
if ( match[1].length > 0 ){
if ( node.textContent.length > length )
next = node.splitText( length );
group = false;
wrapper.className = "sentence sentence-end";
}
else
{
wrapper.className = "sentence";
group = true;
}
var parent = node.parentNode;
var sibling = node.nextSibling;
wrapper.appendChild( node );
if ( sibling )
parent.insertBefore( wrapper, sibling );
else
parent.appendChild( wrapper );
node = next;
}
}
}
else if ( node.nodeType === Node.ELEMENT_NODE || node.nodeType === Node.DOCUMENT_NODE )
{
stack.unshift.apply( stack, node.childNodes );
}
}
}
parseText( document.body );