【问题标题】:Howto exclude jpeg-names from regexp replace?如何从正则表达式替换中排除 jpeg 名称?
【发布时间】:2016-12-09 09:35:30
【问题描述】:

我正在为文档站点使用搜索功能,在选择搜索命中时会显示突出显示文本的页面(就像 pdf 阅读器或 netbeans 会做的那样)。

为了实现高光,我使用了 javascript:

function searchHighlight(searchTxt) {
  var target = $('#page').html();
  var re = new RegExp(searchTxt, 'gi');
  target = target.replace(
    re,
    '<span class="high">' + searchTxt + '</span>'
  );
  $('#page').html(target);
}

问题/疑问:

由于页面包含基于 md5 文件名的图像,因此某些搜索会混淆图像 src。

搜索“1000”会扭曲

<img src="53451000abababababa---.jpg"

<img src="5334<span class="hl">1000</span>abababab--.jpg">

是否可以用正则表达式解决这个问题,以某种方式排除“.jpg”的任何内容?

或者有没有可能,在highligting之前用占位符替换图像,在replace之后恢复到src?

例子:

  • 将所有 替换为 {{I-01}}、{{I-02}} 等,并将真正的 src 保存在 var 中。
  • 执行上述替换。
  • 从 {{I-01}} 恢复到

DOM 操作当然是一种选择,但我认为这可以通过正则表达式以某种方式完成,但是,我的正则表达式技能非常缺乏。

更新 这段代码现在对我有用:

function searchHighlight(searchTxt) {    
var stack = new Array();
var stackPtr = 0;
var target = $('#page').html();
//pre
target = target.replace(/<img.+?>/gi,function(match) {
  stack[stackPtr] = match;
  return '{{im' + (stackPtr++) + '}}';
});
//replace
var re = new RegExp(searchTxt, 'gi');
target = target.replace(re,'<span class="high">' + searchTxt + '</span>');
//post
stackPtr = 0;
target = target.replace(/{{im.+?}}/gi,function(match) {
    return stack[stackPtr++];
});
$('#page').html(target);
}

【问题讨论】:

  • 也许你想办法解决这个问题,但你会遇到其他问题,因为你的方法不好。不要试图用正则表达式来理解 HTML。
  • @ankitbug94,我认为你没有抓住重点。
  • 您能否在问题中包含 html#page 元素?
  • searchTxt 是用户输入吗?
  • 您对searchTxt=img&gt; 等的计划是什么,这将彻底破坏您的HTML

标签: javascript regex documentation


【解决方案1】:

一种方法是创建一个包含所有可能的有效搜索词的数组。将术语设置为 .textContent&lt;span&gt; 元素中的 #page 父元素。

searchHighlight 函数检查 searchTxt 是否匹配数组中的元素。如果searchTxt 匹配数组元素,则使用匹配数组元素的索引选择span 元素,在匹配的#page span 元素处切换"high" .className,否则通知用户searchTxt 不匹配任何有效的搜索词.

$(function() {
  var words = [];
  var input = $("input[type=text]");
  var button = $("input[type=button][value=Search]");
  var reset = $("input[type=button][value=Reset]");
  var label = $("label");
  var page = $("#page");
  var contents = $("h1, p", page).contents()
    .filter(function() {
      return this.nodeType === 3 && /\w+/.test(this.nodeValue)
    }).map(function(i, text) {
      var span = text.nodeValue.split(/\s/).filter(Boolean)
        .map(function(word, index) {
          words.push(word);
          return "<span>" + word + "</span> "
        });
      $(text.parentElement).find(text).replaceWith(span);
    })
  var spans = $("span", page);
  button.on("click", function(event) {
    spans.removeClass("high");
    label.html("");
    if (input.val().length && /\w+/.test(input.val())) {
      var terms = input.val().match(/\w+/g);
      var indexes = $.map(terms, function(term) {
        var search = $.map(words, function(word, index) {
          return word.toLowerCase().indexOf(term.toLowerCase()) > -1 && index
        }).filter(Boolean);
        return search
      });
      if (indexes.length) {
        $.each(indexes, function(_, index) {
          spans.eq(index).addClass("high")
        })
      } else {
        label.html("Search term <em>" + input.val() + "</em> not found.");
      }
    }
  });
  reset.on("click", function(event) {
    spans.removeClass("high");
    input.val("");
    label.html("");
  })
})
.high {
  background-color: #caf;
}
label em {
  font-weight: bold;
  background-color: darkorange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" />
<input type="button" value="Search" />
<input type="button" value="Reset" />
<label></label>
<div id="page" style="max-width:500px;border:1px solid #ccc;">
  <h1 style="margin:0px;">test of replace</h1>
  <p>After Luke comes to Dagobah, Yoda initially withholds his true identity. He’s trying to get a sense of who Luke is as a person; Yoda understands that there’s a lot at risk in training Luke to be a Jedi, especially considering what happened with his
    father.
    <img style="float:right;" width="200" src="http://a.dilcdn.com/bl/wp-content/uploads/sites/6/2013/11/04-400x225.jpg">And Yoda is not impressed — Luke is impatient and selfish. With “Adventure. Excitement. A Jedi craves not these things,” the Jedi Master makes clear that Luke must understand the significance and meaning of the journey he thinks he wants to make.
    It’s an important lesson for Luke and for audiences, because when Luke faces Vader at the film’s climax, we see the stakes involved in the life of a Jedi</p>
  <p>Now Yoda-search works, however a search on "sites" will break the image-link. (Yes, I know this implementation isn't perfect but I'm dealing with reality)</p>
</div>

【讨论】:

  • 感谢您的建议。然而,它是一个大约 1000 页的文档站点。有效的搜索词应该是广泛的。
  • “太宽泛”是什么意思?每个单词或您确定为搜索词的单词都可以放在&lt;span&gt; 元素内#page 元素内。您已经在 searchHighlight 函数中做同样的事情。所描述的方法无需修改html,而不是切换元素的.className。页数无关紧要。
  • 从我的角度来看,我真的看不出这将如何解决任何问题。假设“1000”应该是一个有效的搜索词,那么它仍然会破坏上面的 img-src。
  • 不,它不会,因为RegExp 不会用于更改任何html。切换&lt;span&gt; 元素的"high" .className,其中.textContent 包含"1000"&lt;img&gt; 元素以及任何其他省略的元素都不会成为该过程的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多