Challenge : Our users have access to an "contentEditable" DIV in which a JS library inserts HTML in it. Here's how we thought the HTML should show up in the contentEditable :
<span class="stylish-blue-button">
<span style="display:none;">[data-user="12345" data-userId="678910"]</span>
John Smith
<span style="display:none;">[/]</span>
</span>
...Blablabla some other text...
We hand over this HTML to PHP, where we execute strip_tags(). This should give us :
[data-user="12345" data-userId="678910"]John Smith[/] ...Blablabla some other text...
Question : When rendering the text on the page, we were wondering if there was a secure/reliable way to have the above custom markdown converted to (before handing it to Handlebars.js) :
<span class="stylish-blue-button" data-user="12345" data-userId="678910">John Smith</span> ...Blablabla some other text...
Why : This assures us that the user generated content was handled safely, all while keeping the user generated markdown in the contentEditable "pretty" ("stylish-blue-button" class).
If you have any suggestions to make this whole process simpler, we're opened to changing our markdown's format.
Thank you so much!
You could use a regex like this:
$string = '<span class="stylish-blue-button">
<span style="display:none;">[data-user="12345" data-userId="678910"]</span>
John Smith
<span style="display:none;">[/]</span>
</span>
...Blablabla some other text...';
echo preg_replace('~\[(data-user="\d+")\h+(data-userId="\d+")\]\s*(.+?)\s*\[/\]\s*(.*)~s', '<span $1 $2>$3</span>$4', trim(strip_tags($string)));
Here's a regex101 demo explaining exactly what that regex is doing. If you have a particular questions please ask.
Output:
<span data-user="12345" data-userId="678910">John Smith</span>...Blablabla some other text...
A few quick regex notes.
* is a quantifier meaning zero or more of the preceding character.
+ is a quantifier meaning one or more (aka it is required) of the preceding character.
\s is a whitespace character.
\h is a horizontal space.
. is any single character.
\d is a single number (0-9).
() are capturing groups they capture into $1, $2 etc. in the order they were found.
Looking at that regex again a quick note: This \[/\] is read as literal [/]. The backslashes are escaping the [] which otherwise would create a character class (meaning only the / character would be allowed there).
Multi-instances:
$string = '<span class="stylish-blue-button">
<span style="display:none;">[data-user="12345" data-userId="678910"]</span>
John Smith
<span style="display:none;">[/]</span>
</span>
...Blablabla some other text...
<span class="stylish-blue-button">
<span style="display:none;">[data-user="12345" data-userId="678910"]</span>
John Smith
<span style="display:none;">[/]</span>
</span>
...Blablabla some other text...
<span class="stylish-blue-button">
<span style="display:none;">[data-user="12345" data-userId="678910"]</span>
John Smith
<span style="display:none;">[/]</span>
</span>
...Blablabla some other text...';
echo preg_replace('~\s*\[(data-user="\d+")\h+(data-userId="\d+")\]\s*(.+?)\s*\[/\]\s*~s', '<span $1 $2>$3</span>', trim(strip_tags($string)));
Output:
<span data-user="12345" data-userId="678910">John Smith</span>...Blablabla some other text...<span data-user="12345" data-userId="678910">John Smith</span>...Blablabla some other text...<span data-user="12345" data-userId="678910">John Smith</span>...Blablabla some other text...
For looser Ids just change the \d+ to [a-zA-Z0-9 ]+.
So:
preg_replace('~\s*\[(data-user="\d+")\h+(data-userId="[a-zA-Z0-9 ]+")\]\s*(.+?)\s*\[/\]\s*~s'
Related
Had an idea for my portfolio, whereby I would wrap my surname in JSX component tags - JOE - with the tags as plain old paragraph text within spans, then style. But the tags are obviously being interpreted by my code editor as JSX tags, rather than text, throwing errors.
Does anyone know of an element that would wrap around the tags, rendering them as text? Tried a few things but can't figure it out.
<h1> JOE <span className='neon'> < </span> BLOGGS <span className='neon'> /> </span> </h1>
To render HTML markup as text you can use HTML entities. Replace < with < and > with >:
<h1> JOE <span className='neon'> < </span> BLOGGS <span className='neon'> /> </span> </h1>
You can try wrapping it in curly braces {}, which denote it as a JavaScript expression
<h1> JOE <span className='neon'> {'<'} </span> BLOGGS <span className='neon'> {'/>'} </span> </h1>
You can try {'/>'} to show the characters as text
Either you can use direct {'<'}, {'>'} as an expression or HTML entities <
With AngularJs, I am trying to display currency exchange with image. Here is my Razor code below.
<span ng-controller="CurrencyController">
<span ng-bind="currencies"></span>
</span>
and I am sending the below text from controller
string text = "Dollar : 1.7 <img src=\"~/Images/Currency/up.png\">";
when the HTML is rendered, I took a look at the source in Chrome, and I saw the HTML below...
<span class="ng-binding">
"Dollar: 1.7 <img src="~/Images/Currency/down.png">"
</span>
Why is the rendered text in HTML is surrounded with double quotation? how can I fix this?
You should be using ng-bind-html, as stated in the docs, is the directive used to render html.
ng-bind should only be used if you cant to render a simple html text node.
So, your code should look like this:
<span ng-controller="CurrencyController">
<span ng-bind-html="currencies"></span>
</span>
I have this HTML code:
<span class="apparatus type-substantive">
<span class="reading HQ1">I there’s the </span>
<span class="reading TTQ1 BQ1">ay, there's the </span>
<span class="reading HQ2 BQ2 BF BE HaF MW GBE HJ DB4 BR PE TW TS TTQ2 TTF RSM"> that is the </span>
</span>
And I want to inject "<" and ">" before and after the one with class HQ2 (third span), and { and } before and after the one which has class HQ1 (first span), so I've done this:
$('span.HQ2').prepend('<span class="pended"><</span>').append('<span class="pended">&t;</span>').siblings('.HQ1').prepend('<span class="pended">{</span>').append('<span class="pended">}</span>').css('color','#217b26');
The problem is that the result is not the one I expected, because the second append and prepend are not working, these only work if I remove the span tags and leave the "{" and "}" alone. The .css() works as expected, so the selection is done properly with .siblings(). I think the problem may rely in the result that .siblings() is giving me, maybe it does not accept prepending and appending HTML tags or something. I don't know...
Could you enlighten me?
Thank you very much.
try '\' before greater than and less than marks. this will ensure they are interpreted as text:
$('span.HQ2').prepend('<span class="pended">\<</span>').append('<span class="pended">\></span>').siblings('.HQ1').prepend('<span class="pended">{</span>').append('<span class="pended">}</span>').css('color', '#217b26');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="apparatus type-substantive">
<span class="reading HQ1">I there’s the </span>
<span class="reading TTQ1 BQ1">ay, there's the </span>
<span class="reading HQ2 BQ2 BF BE HaF MW GBE HJ DB4 BR PE TW TS TTQ2 TTF RSM"> that is the </span>
</span>
Today I've found out why this wasn't working... apparently I forgot I had a piece of jquery later in the same code preventing me from doing this... I've been fooled by my own code. :/
Thank you all, anyways.
I need to wrap a sequence or group of tandem english characters in a <span> tag.
In the other words I want to change the style of english language in my texts. So I need to find english characters and wrap them in a <span> tag.
The method I'm using now puts every single english character in a <span> tag but I want the group of these chars to be in a single <span> tag.
edit: I want to select and replace a word that is in english language.
For example "russian russian english russian"
What I need is wrap the english "Characters" in <span> tag:
"russian russian <span class='eng'>english</span> russian"
As I understand you need to find words.
So you can use something like:
\b\S+\b
Or if you want replace only word "english" :
Regex:
\b(english)\b
Change to :
<span class='eng'>$1</span>
This text :english russian russian english russian english english.
Changes to this: <span class='eng'>english</span> russian russian <span class='eng'>english</span> russian <span class='eng'>english</span> <span class='eng'>english</span>.
Don't forget to add case insensitive.
I'm using this regex
<a [^>]*href[ ]*=[ ]*\"|'[^>]\"|'[^>]*>
to search in example string:
idhasidhioashdoihas <a onclick=alert('blablabla') href='www.hello.com'
onclick=alert('blablabla') > asdfsgdufisdugfusdg
It should match
<a onclick=alert('blablabla') href='www.hello.com'onclick=alert('blablabla') >
but it only matches
'blablabla') href='www.hello.com' onclick=alert('blablabla') >
Any idea where is the problem?
Your | is in the wrong place:
<a [^>]*href[ ]*=[ ]*\"|'[^>]\"|'[^>]*> is effectively:
<a [^>]*href[ ]*=[ ]*\" or '[^>]\" or '[^>]*>
If you want to mark " or ' in this exact place use []:
<a [^>]*href\s*=\s*["'][^>]*["'][^>]*>
Example:
a = "idhasidhioashdoihas <a onclick=alert('blablabla') href='www.hello.com' onclick=alert('blablabla') > asdfsgdufisdugfusdg";
a.match(/<a [^>]*href\s*=\s*["'][^>]*["'][^>]*>/)
["<a onclick=alert('blablabla') href='www.hello.com' onclick=alert('blablabla') >"]
You don't correctly test for the two possible attribute value delimiters. You can use this one :
/<a [^>]*href[ ]*=[ ]*[\"']?[^>][\"']?[^>]*>/
I just changed \"|' to [\"']? (note that it's possible not to have quotes at all, hence the ?)
The character classes you use are not always appropriate and you must surround your alternation by a group (ie: (?:'|")), but you don't need it. You can try this, with the same idea:
<a (?:[^h>]+|h(?!ref))*\bhref\s*=\s*["'][^"']*["'][^>]*>
But if you want only to find a link tag, you can use <a.+?> as thg435 suggests it.
(Note that the href value is not always between quotes:
<a (?:[^h>]+|h(?!ref))*\bhref\s*=\s*(?:["'][^"']*["']|[^\s>]*)[^>]*>
(or to be sure to have the same quotes)
<a (?:[^h>]+|h(?!ref))*\bhref\s*=\s*(?:(["'])(?:\\\1|[^"']+|(?!\1)["'])*\1|[^\s>]*)[^>]*>