regex to find html class name - html

I have the following html code :
<aside id="side">
<a class="active" href="#!"> some text <a>
<a href="#!"> some text <a>
<p> active </p>
</aside>
I am looking for a regex that only finds the 'active' string that is inside <aside id="side"></aside> and also 'active' should be value of class and something like <p> active </p> should not be match.
I try to use :
<aside.*[\s\S\n]class="active".*</aside>
but I dont find any match.

Try this
/class="\w*\W*active\W*\w*"/
Example

The problem with your regex is that the . in .* does not catch newlines. A JavaScript regex has no modifier to have newlines included in ., but you can use [\s\S]* as a workaround. The workaround skips over all whitespace and non-whitespace.
Here is a working code snipped that demonstrates that:
var html1 =
'<aside id="side">\n' +
' <a class="active" href="#!"> some text <a>\n' +
' <a href="#!"> some text <a>\n' +
' <p> active </p>\n' +
'</aside>';
var html2 =
'<bside id="side">\n' +
' <a class="active" href="#!"> some text <a>\n' +
' <a href="#!"> some text <a>\n' +
' <p> active </p>\n' +
'</bside>';
var re = /<aside [\s\S]* class="active"[\s\S]*<\/aside>/;
console.log('test html1: ' + re.test(html1));
console.log('test html2: ' + re.test(html2));

Related

How to extract ``href`` and ``TEXT`` in the below situation?

My HTML code looks like this:
<div class="menu">
<a class="menu-item" href="........."> TEXT</a>
<a class="menu-item" href="........."> TEXT</a>
<a class="menu-item" href="........."> TEXT</a>
<a class="menu-item" href="........."> TEXT</a>
</div>
I am using cheerio for scraping. I want to loop through the anchor tags and extract TEXT and href but am unable to achieve so.
Please someone guide me through this.
Here is one of the ways to extract 'href' and 'TEXT'
const $=cheerio.load(....response data....);
const listItems= $(".menu a");
listItems.each((idx, el)=>{
const Text= $(el).text();
const href= $(el).attr("href");
console.log("text"+ text+ " href" + href);
})
The line const listItems= $(".menu a"); is helping to identify the anchor tags in div and upon looping we can extract the data in the anchor usingconst Text= $(el).text(); and const href= $(el).attr("href");
This is working for me.

select span text with jquery

I have this html code, I want get span text when click in reply, but I have multiple of this code in my page and this select only first item, this is my code
<div class="display-comment" style="margin-right: 10px">
<div class="userProfileImageForComment">
<img src="{{asset('profile-media/'.$comment->user->profileimg)}}" alt="">
</div>
<span id="userName">{{ $comment->user->username }}</span>
<p>{{ $comment->comment }}</p>
<div class="comentActionAndDate">
<span>
{{ jdate($comment->created_at)->ago() }}
</span>
<a id="reply">
reply
</a>
</div>
and script is
<script>
$('#reply').click(function(){
var username = "#" + $('#userName').text() + " ";
$('#comment').val('');
$('#comment').val(username);
$('#comment').after( "<input type=\"hidden\" name=\"comment_id\" value=\"{{ $comment->id }}\" />" )
});
</script>
you can do get your span text with this comnmand:
$('#userName')[0].innerText
anything else?
var spanText = $(".comentActionAndDate span").html();
I assume this is for a comments thread though, in which case you should use relative finding to locate the text.
$('#reply').click(function(){
var spanText = $(this).find(".comentActionAndDate").children("span").html();
// Other stuff you might want to do
});
You also should not be using an ID for that reply button if it is being generated more than once. You should also be using a <button> not an <a> tag as the a tag is used for links.
The most correct approach would be to use a function onclick of the reply button:
<button onclick="getSpan(this);">reply</button>
JS:
function getSpan(ele) {
var spanText = $(ele).find(".comentActionAndDate").children("span").html();
// Other stuff you might want to do
}

How to style part of text string before a symbol

I have text which comes from for loop, for example "Hello: how are you?" and "Hi: I am fine".
I want to make the text before : to be in bold. So above example I need "Hello" and "Hi" to be bold as they are in front of ":"
So actually my html is . There is a for loop on node
<div >
<a>
{{node.childrenCount == 0 ? node.code + ': ' + node.name: node.code + ': '+ node.name + ' ('+ node.childrenCount + ')' }}
</a>
</div>
How do I do that using CSS?
It's not possible with CSS without modifying the markup.
If you can modify the template, you could write:
<div>
<a><strong>{{ node.code }}</strong>: {{ node.name }}</a>
</div>
(Edit to address ternary in updated question)
That ternary is conditionally rendering the childrenCount in parentheses if it isn't equal to 0, which could be written as:
<div>
<a><strong>{{ node.code }}</strong>: {{ node.name }}{{ node.childrenCount !== 0 ? ' (' + node.childrenCount + ')' : '' }}</a>
</div>
Try to use:
let str = "Hello: how are you? Hi: Im fine?";
str = str.replace(/[a-zA-Z]+:/g, '<strong>$&</strong>');
//result: "<strong>Hello:</strong> how are you? <strong>Hi:</strong> Im fine?"
Using strong tag helps screen readers, but you can also use b tag or modify a span tag with css property font-weight:bold;.
<strong>Hello:</strong>How are you?
just wrap what you want in < b > tags
<b>Hello:</b>How are you? <br>
<b>Hi:</b> I am fine".

Elegant way to show href based on condition

I have to show an <a> tag. But depending on whether a value exists or not, I need to set href.
This is what I have:
<a ng-show="source.element!=0" "href="#/resource/{{source.a}}/{{source.b}}/val">
{{source.element}})
</a>
<a ng-show="source.element==0" "href="">{{source.element}}</a>
If source.element is 0 , then nothing should happen on clicking on the value of source.element (href="")
Else, the page must be redirected according to the href.
Is there a better way to do this since this duplicates code?
Thanks..
create a method in scope
$scope.getUrl = function(source){
return source.element==0 ? '#' : '#/resource/'+source.a+'/'+source.b+'/val';
}
then call from view
<a ng-href="{{getUrl(source)}}">
{{source.element}})
</a>
For angular markup it's better to use ngHref .
Becuse if user click on href before angular load it'll go the wrong address.
You can use ng-if
<div ng-if="source.element!=0"><a ng-href="your-url">{{sourceElement}</a></div>
<div ng-if="source.element==0"><a ng-href="">{{sourceElement}}</a></div>
ngif Documentation
Use ng-switch to reduce the number of watches and code duplication:
<span ng-switch="source.element">
<a ng-switch-when="0">
{{source.element}}
</a>
<a ng-switch-default ng-href="#/resource/{{source.a}}/{{source.b}}/val">
{{source.element}}
</a>
</span>
In your controller:
$scope.source.url = $scope.source.element === 0 ? '' : '#/resource/' + $scope.source.a + '/' + $,scope.source.b + '/val';
And in your markup
<a "ng-Href={{source.url}}>{{source.element}}</a>
Create a directive with two attributes like condition and url:
app.directive('anchor', function() {
return {
scope: {
condition: '=expr',
url: '#',
prompt: '#'
},
restrict: 'AE',
replace: 'true',
template: '<div>' +
'<div ng-if="condition">' +
'<a ng-href="{{url}}">{{prompt}}</a>' +
'</div>' +
'<div ng-if="!condition">{{prompt}}</div>' +
'</div>'
};
});
<anchor expr="1 === 1" url="#/test" prompt="test" />
The jsfiddle link.

Regex for no space between attributes html

How to detected no space between attributes.
Example:
<div style="margin:37px;"/></div>
<span title=''style="margin:37px;" /></span>
<span title="" style="margin:37px;" /></span>
<a title="u" hghghgh title="j" >
<a title=""gg ff>
correct: 1,3,4
incorrect: 2,5
How to detected incorrect?
I've tried with this:
<(.*?=(['"]).*?\2)([\S].*)|(^/)>
But it's not working.
You should not use regex to parse HTML, unless for learning purpose.
http://regexr.com/3cge1
<\w+(\s+[\w-]+(=(['"]?)[^"']*\3)?)*\s*/?>
This regular expression matches even if you don't have any attribute at all. It works for self-closing tags, and if the attribute has no value.
<\w+ Match opening < and \w characters.
(\s+[\w-]+(=(['"])[^"']*\3)?)* zero or more attributes that must start with a white space. It contains two parts:
\s+[\w-]+ attribute name after mandatory space
(=(['"])[^"']*\3)? optional attribute value
\s*/?> optional white space and optional / followed by closing >.
Here is a test for the strings:
var re = /<\w+(\s+[\w-]+(=(['"]?)[^"']*\3)?)*\s*\/?>/g;
! '<div style="margin:37px;"/></div>'.match(re);
false
! '<span title=\'\'style="margin:37px;" /></span>'.match(re);
true
! '<span title="" style="margin:37px;" /></span>'.match(re);
false
! '<a title="u" hghghgh title="j" >'.match(re);
false
! '<a title=""gg ff>'.match(re);
true
Display all incorrect tags:
var html = '<div style="margin:37px;"></div> <span title=\'\'style="margin:37px;"/><a title=""gg ff/> <span title="" style="margin:37px;" /></span> <a title="u" hghghgh title="j"example> <a title=""gg ff>';
var tagRegex = /<\w+[^>]*\/?>/g;
var validRegex = /<\w+(\s+[\w-]+(=(['"]?)[^"']*\3)?)*\s*\/?>/g;
html.match(tagRegex).forEach(function(m) {
if(!m.match(validRegex)) {
console.log('Incorrect', m);
}
});
Will output
Incorrect <span title=''style="margin:37px;"/>
Incorrect <a title=""gg ff/>
Incorrect <a title="u" hghghgh title="j"example>
Incorrect <a title=""gg ff>
Update for the comments
<\w+(\s+[\w-]+(="[^"]*"|='[^']*'|=[\w-]+)?)*\s*/?>
I got this pattern to work, finding incorrect lines 2 and 5 as you requested:
>>> import re
>>> p = r'<[a-z]+\s[a-z]+=[\'\"][\w;:]*[\"\'][\w]+.*'
>>> html = """
<div style="margin:37px;"/></div>
<span title=''style="margin:37px;" /></span>
<span title="" style="margin:37px;" /></span>
<a title="u" hghghgh title="j" >
<a title=""gg ff>
"""
>>> bad = re.findall(p, html)
>>> print '\n'.join(bad)
<span title=''style="margin:37px;" /></span>
<a title=""gg ff>
regex broken down:
p = r'<[a-z]+\s[a-z]+=[\'\"][\w;:]*[\"\'][\w]+.*'
< - starting bracket
[a-z]+\s - 1 or more lowercase letters followed by a space
[a-z]+= - 1 or more lowercase letters followed by an equals sign
[\'\"] - match a single or double quote one time
[\w;:]* - match an alphnumeric character (a-zA-Z0-9_) or a colon or semi-colon 0 or more times
[\"\'] - again match a single or double quote one time
[\w]+ - match an alphanumeric character one or more times(this catches the lack of a space you wanted to detect) ***
.* - match anything 0 or more times(gets rest of the line)
Try this regex , i think it will work
<\w*[^=]*=["'][\w;:]*["'][\s/]+[^>]*>
< - starting bracket
\w* - one or more alphanumeric character
[^=]*= - It will cover all the character till '=' shows up
["'][\w;:]*["'] - this will match two cases
1. one with single quote with having strings optional
2. one with double quote with having strings optional
[\s/]+ - match the space or '\' atleast one occurence
[^>]* - this will match all the character till '>' closing bracket
Not sure about this I am not so experienced at regex but this looks like it is working well
JS Fiddle
<([a-z]+)(\s+[a-z\-]+(="[^"]*")?)*\s*\/?>([^<]+(<\/$1>))?
Currently <([a-z]+) will mostly work but with web component and <ng-* this would better be \w+
---------------
Output:
<div style="margin:37px;">div</div> correct
<span title=" style="margin:37px;" />span1</span> incorrect
<span title="" style="margin:37px;" />span2</span> correct
<a title="u" title="j">link</a> correct
<a title=""href="" alt="" required>test</a> incorrect
<img src="" data-abc="" required> correct
<input type=""style="" /> incorrect