忽略HTML标记以突出显示匹配的单词
我希望在突出显示与搜索输入匹配的字词后,用新的内容替换HTML模板内容。
I want to replace HTML template content with new one after highlighting the words those match the search input.
如片段所示,我使用的是高亮过滤器通过添加& zwj;< span class =highlight> $ 1& zwj;< / span>
。
As shown in the snippet, I am using a highlight filter that adds yellow background to matched words by adding ‍<span class="highlighted">$1‍</span>
.
问题
问题是有时突出显示不会执行,我可以' t弄清楚为什么,例如,当搜索 accountin
时,它会突出显示,但在搜索会计
时,然后它没有突出显示。
The problem is that sometimes highlighting doesn't execute and I can't figure out why, for example, when searching for accountin
, then it is highlighted, but when searching for accounting
, then it's not highlighted.
仅当匹配的单词位于某些子标记内时才会出现此问题,例如< bold>
和< tag>
和其他人,你可以尝试搜索会计
,你会看到什么我的意思是。为什么会这样?以及如何修复它?
This problem occurs only when the matched word is inside some sub-tags such as <bold>
and <tag>
and others, you can try to search for accounting
and you'll see what I mean. Why does this happen? and how to fix it?
问题二
在HTML中,我我使用的材料图标,如< md-icon class =material-icons ltr>文件夹< / md-icon>
,以及搜索文件夹,然后突出显示在此图标上。
In the HTML, I am using material icons such as <md-icon class="material-icons ltr">folder</md-icon>
, and when searching for folder
, then the the highlighting will occur on this icon.
即使我使用图标作为svg,如 < md-icon md-svg-src =path / user.svg>< / md-icon>
,同样的问题也会发生。
Even if I use icons as svg like <md-icon md-svg-src="path/user.svg"></md-icon>
, the same problem will happen.
那么,有什么方法可以避免这种情况吗?
So, is there any way to avoid this?
angular.module("myApp", ["ngMaterial"])
.filter('highlight', function ($sce) {
function mapText(text,tag,tagvalue){
var reg = new RegExp("[\>][^\<\>.]*"+tag+"[^\<\>.][\<]*","gi");
var result = text.replace(reg,function(item,exp){
var subRegex = new RegExp(tag,"gi");
return item.replace(subRegex,tagvalue);
});
return result;
}
return function (text, searchSrting) {
if(searchSrting){
searchSrting = searchSrting.split(/\s+/);
if(typeof text !== "undefined") {
for (var i = 0; i < searchSrting.length; i++) {
if(searchSrting[i]==""){
continue;
}
else{
var tagvalue = '‍<span class="highlighted">' + searchSrting[i] + '‍</span>';
text = mapText(text, searchSrting[i], tagvalue);
}
}
}
return $sce.trustAsHtml(text)
}
}
})
.controller("main", function($scope){
$scope.searchString="";
$scope.content="<module> <ti-tle>User Management</ti-tle><br><tag-group><tag>User Management</tag></tag-group><info-group><info><md-icon class='material-icons ltr'>perm_identity</md-icon>published by: Ha ba</info> <info><md-icon class='material-icons ltr'>folder</md-icon>User Management</info><info><md-icon class='material-icons ltr'>publish</md-icon>published: 25 May 2016</info></info-group><hr>In <bold>AMe</bold>, you can manage multiple bank accounts <br><br> <sub-title> Introduction Accounting</sub-title> The Sales Planner is a useful step-by-step guide created to help you implement your sales funnel <br>Accounting Go to <bold>Accounting</bold> ‣ <bold>Configuration</bold> ‣ <bold>Bank Accounts</bold> and click on the Bank item. Edit it <note><md-icon class='material-icons'>error_outline</md-icon> will detect the bank account type (e.g. IBAN) to allow some payment method like SEPA. </note> <br><br> <sub-title> Set up your first sales team </sub-title> For example, if within your company Tim is selling products and John is selling maintenance contracts, they will be assigned to different teams and will only receive opportunities that make sense to them. <br><br> <sub-title> Set up incoming email to generate opportunities </sub-title> In CRM, one way to generate opportunities into your sales team is to create a generic email address as a trigger. </module>";
})
module{
font-size: 14px;
color: #484848;
}
ti-tle {
font-size: x-large;
color: rgb(50, 118, 177);
display: block;
font-weight: bold;
}
tag-group{
display: block;
line-height: 3;
}
tag{
background-color: #daebe8;
padding:2px 6px;
font-weight: bold;
font-size: 12px;
margin: 2px;
border-radius: 4px;
cursor: pointer;
color: #667292;
}
tag:hover{
background-color: #87bdd8;
}
info-group{display: block}
info{
color: gray;
margin: 4px;
font-size: 12px;
}
sub-title{
font-weight: bold;
font-size: 18px;
display: block;
line-height: 2;
}
img{
display: block;
margin: 30px 0;
width: 100%;
}
bold{
font-weight: bold;
}
note{
background-color: antiquewhite;
}
.highlighted {
background: yellow;
}
md-icon{direction: ltr}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.7/angular-aria.js"></script>
<script src="//rawgit.com/angular/bower-material/master/angular-material.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<div ng-app="myApp">
<div ng-controller="main">
<label>search</label>
<input ng-model="searchString"/>
<div ng-if="!searchString">
<module>
<ti-tle>User Management</ti-tle>
<br>
<tag-group>
<tag>User Management</tag>
</tag-group>
<info-group>
<info><md-icon class="material-icons ltr">perm_identity</md-icon>published by: Ha ba</info>
<info><md-icon class="material-icons ltr">folder</md-icon>User Management</info>
<info><md-icon class="material-icons ltr">publish</md-icon>published: 25 May 2016</info>
</info-group>
<hr>
In <bold>AMe</bold>, you can manage multiple bank accounts
<br><br>
<sub-title>
Introduction Accounting
</sub-title>
The Sales Planner is a useful step-by-step guide created to help you implement your sales funnel
<br>
Accounting
Go to <bold>
Accounting</bold> ‣ <bold>Configuration</bold> ‣ <bold>Bank Accounts</bold> and click on the Bank item. Edit it
<note><md-icon class="material-icons">error_outline</md-icon>
will detect the bank account type (e.g. IBAN) to allow some payment method like SEPA.
</note>
<br><br>
<sub-title>
Set up your first sales team
</sub-title>
For example, if within your company Tim is selling products and John is selling maintenance contracts, they will be assigned to different teams and will only receive opportunities that make sense to them.
<br><br>
<sub-title>
Set up incoming email to generate opportunities
</sub-title>
In CRM, one way to generate opportunities into your sales team is to create a generic email address as a trigger. For example, if
</module>
</div>
<div ng-if="searchString" ng-bind-html="content | highlight:searchString"></div>
</div>
</div>
首先,我很抱歉快速测试答案。
Firstly I am sorry for quick tested answer.
以下是您的答案:
var reg = new RegExp("[\>][^\<\>.]*"+tag+"[^\<\>.][\<]*","gi");
此行正则表达式搜索任何字符但不搜索'><'。这是你的代码工作错误正确的一个在这里:
in this line regex searchs for any character but not '><'. this is whay your code is working wrong correct one is here:
var reg = new RegExp("[\>][^\<\>.]*"+tag+"[^\<\>.]*[\<]*","gi");
第2部分:在此代码中,您将逐个替换单词。所以当你替换一个单词时,第二个包含正则表达式不匹配的单词。示例:
Part 2: in this code you are replacing words one by one. so when you replaced one word is second includes that word regex will not match. Example:
我们的重点词是火和消防员。
Our highlight words are fire and fireman.
var text = "<div>fireman has killed fire</div>";
在第一个循环文本后将如下:
after first loop text will be like:
text = "<div><highlight>fire</highlight>man has killed <highlight>fire</highlight></div>";
所以我们的正则表达式与新文本中的第二个字不匹配。
so our regex won't match second word in this new text.
但是如果我们按文本长度对数组进行排序。这个问题将得到解决。
but if we sort our array by text length. this problem will be solved.
在< md-icon class =material-icons ltr>文件夹< / md-icon>
案例看起来像这个正则表达式不会帮助你。如果你想在项目中使用正则表达式执行此操作,可以在正则表达式中添加所有案例。
in <md-icon class="material-icons ltr">folder</md-icon>
case looks like this regex won't help you. if you want to do this with regex on your project you can add all of cases in your regex.
但像这样的正则表达式中的特殊用法......我认为这不是最好的方法。
But spesific usages in regex like this... I don't think that's the best way to do that.
因为;将来,如果您决定更改图标库。你也必须改变你的正则表达式。而且正则表达式并不是第一个看起来可以理解的语言。最后,这将是一个非常非常糟糕的隐藏业务。
Because; in the future if you decide to change your icon library. you will have to change your regex too. And regex is not first look understandable lanugage. In the end this will be a very very bad hidden bussiness.
我希望你能找到你想要的东西。
I hope you can find what you're looking for.