Provided both the answers by @Simon and @Booboo failed to solve the problem for such string(s):
<a style='margin:12px; margin-left:13px'><p style='margin-top:13px'></p>Margin</a> Hello margin top <p margin:13><p style='margin:123;margin-right:12px'><margin></p>
I had to answer the question myself.
So what I did was build up the following regex:
/<[a-z]+[^>]*style\s*=\s*['"][^'">]*margin[^>]*/gi
- First look for start of an HTML tag
(<)
- Next at least one alphabet is required indicating the HTML tag
([a-z]+)
- Next any number of characters is accepted, except for a
>, till a 'style' is found ([^>]*style)
- Next any number of space between the
style and '=' (\s*=)
- Also any number of space between the right of equal and a quote,
' or ", (\s*['"])
- Next accept any number of characters, except
', " or > , till the margin is found ([^'">]*margin)
- Next accept any number of characters, except
> ([^>]*)
The gi and flags representing to search globally and case insensitivity.
Also the code example to replace the margin attributes with margin is as follows:
var regex = /<[a-z]+[^>]*style\s*=\s*['"][^'">]*margin[^'">]*/gi;
var str = "<a style='margin:12px; margin-left:13px'><p style='margin-top:13px'></p>Margin</a> Hello margin top <p margin:13><p style='margin:123;margin-right:12px'><margin></p>";
var new_s = str.replace(regex,
function(match) {
return match.replace(/margin/gi, 'padding');
}
);
console.log(new_s);
And the output:
<a style='padding:12px; padding-left:13px'><p style='padding-top:13px'></p>Margin</a> Hello margin top <p margin:13><p style='padding:123;padding-right:12px'><margin></p>
Also you can see the Regex details here.
And how the provided other answers behave wrong:
On the other hand the output of regex by @Simon:
Regex:
/<\s*[a-z]+.*?style\s*=\s*"(?<margin>margin).*?".*?\/?>/gsi
Output:
<a style='margin:12px; margin-left:13px'><p style='margin-top:13px'></p>Margin</a> Hello margin top <p margin:13><p style='margin:123;margin-right:12px'><margin></p>
And also @Booboo regex and output:
Regex:
/[a-z]+\s+(?:(?!>).*?)\bstyle\s*=\s*(['"])(?:(?!\1).*?)(margin)/gmis
Output:
<a style='padding:12px; margin-left:13px'><p style='padding-top:13px'></p>Margin</a> Hello margin top <p padding:13><p style='padding:123;margin-right:12px'><margin></p>
EDIT 18-Dec-2019
------------------------------------------------------------------------------
Thanks to @Booboo for pointing out that the regex still might have problems copping with string like:
<img src='../marginally-wrong-documents/a.jpg' style='display: block; margin: 20px;'>
Thus, for above string my regex:
/<[a-z]+[^>]*style\s*=\s*['"][^'">]*margin[^'">]*/gi
and @Booboo's updated regex:
(<[a-z]+\s+(?:(?!>).*?)\bstyle\s*=\s*)(['"])((?:(?!\2)).*?margin(?:(?!\2).)*)(\2)
Will fail.
So to cope with this I have worked out the following changes in the code (keeping the regex same):
var regex = /<[a-z]+[^>]*style\s*=\s*['"][^'">]*margin[^'">]*/gi;
var str = "<img src='../marginally-wrong-documents/a.jpg' style='display: block; margin: 20px;'><a style='margin:12px; margin-left:13px'><p style='margin-top:13px'></p>Margin</a> Hello margin top <p margin:13><p style='margin:123;margin-right:12px'><margin></p>";
var new_s = str.replace(regex,
function(match) {
var regex2 = /margin[ -:]+/gi;
match = match.replace(regex2, function(match2){
return match2.replace(/margin/gi, "padding");
});
return match;
}
);
console.log(new_s);
So what's new with this change:
- Now get the pattern containing the margin pattern as doing before.
- Now for every pattern find out a pattern that contains margin that is the actual regex's logic.
- For every sub pattern again run the new regex to separate out only the margin that is actually representing the CSS margin (-left, -right, -top, -bottom) attribute and replace it with padding.
Also the output for the above code using the new logic:
<img src='../marginally-wrong-documents/a.jpg' style='display: block; padding: 20px;'><a style='padding:12px; padding-left:13px'><p style='padding-top:13px'></p>Margin</a> Hello margin top <p margin:13><p style='padding:123;padding-right:12px'><margin></p>