如何匹配并返回字符串的多个实例,其中单个撇号可以包含在任何索引中?

请注意,’C#’标签是故意包含的,因为我可以在这里接受C#语法,因为我可以选择在客户端和服务器端执行此操作。 阅读下面的“你可能想知道的事情”部分。 此外,还包含了“正则表达式”标记,因为使用正则表达式很可能是解决此问题的最佳方法。

我在这里找到了以下突出插件:

http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html

这是该插件中的代码:

/* highlight v4 Highlights arbitrary terms.  MIT license. Johann Burkard   */ jQuery.fn.highlight = function(pat) { function innerHighlight(node, pat) { var skip = 0; if (node.nodeType == 3) { var pos = node.data.toUpperCase().indexOf(pat); if (pos >= 0) { var spannode = document.createElement('span'); spannode.className = 'highlight'; var middlebit = node.splitText(pos); var endbit = middlebit.splitText(pat.length); var middleclone = middlebit.cloneNode(true); spannode.appendChild(middleclone); middlebit.parentNode.replaceChild(spannode, middlebit); skip = 1; } } else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { for (var i = 0; i < node.childNodes.length; ++i) { i += innerHighlight(node.childNodes[i], pat); } } return skip; } return this.length && pat && pat.length ? this.each(function() { innerHighlight(this, pat.toUpperCase()); }) : this; }; jQuery.fn.removeHighlight = function() { return this.find("span.highlight").each(function() { this.parentNode.firstChild.nodeName; with (this.parentNode) { replaceChild(this.firstChild, this); normalize(); } }).end(); }; 

这个插件非常容易。

如果我想在以下元素中突出显示“Farm”一词的所有实例……(续)

 
Farmers farm at Farmer's Market

…(续)我需要做的就是使用:

 $("#myDiv").highlight("farm"); 

然后它将突出显示“Farmers”和“Farmer’s”中的前四个字符,以及div#myDiv的整个单词“farm” div#myDiv

没问题,但我想用它:

 $("#myDiv").highlight("Farmers"); 

并强调“农民”和“农民”。 当然,问题是我在运行时不知道搜索术语(本例中的术语“Farmers”)的值。 所以我需要在字符串的每个索引处检测不超过一个撇号的所有可能性。 例如,如果我打电话给$("#myDiv").highlight("Farmers"); 就像我上面的代码示例一样,我还需要突出显示原始字符串的每个实例,另外:

  • “农民
  • F’armers
  • Fa’rmers
  • Far’mers
  • Farm’ers
  • Farme’rs
  • 农民
  • 农民

当然,不应突出显示两个或多个撇号的实例,例如“Fa”rmers”。

我想如果我可以包括(被突出显示)像“Fa’rmer’s”这样的词语会很好,但我不会推动我的运气,而且我会做得很好,只是为了获得上面我的项目符号列表中的匹配项,根本只有一个撇号出现在字符串中。

我考虑过正则表达式,但我不太清楚语法,更不用说我不认为我可以用真/假的返回值做任何事情。

反正有没有完成我需要的东西?

你可能想知道的事情:

  1. 高亮插件可以满足我所需的所有不区分大小写的要求,因此根本无需担心。
  2. JavaScript,jQuery甚至C#中提供的语法都是可以接受的,考虑到隐藏的输入字段,我使用来自客户端的值,服务器端,使用我的C#代码填充。
  3. 填充隐藏输入字段的C#代码使用Razor(即,我在C#.Net Web-Pages w / WebMatrix环境中。但是,此代码非常简单,如下所示:

    for (var n = 0; n < searchTermsArray.Length; n++)

    {

      

    }

我正在复制你之前提出的问题的答案。

我想在阅读了其他答案的评论后,我已经弄明白你的目的是什么。 你不需要一个可以为任何可能的输入做这个的正则表达式,你已经输入,并且你需要构建一个匹配它及其变体的正则表达式。 你需要做的就是这个。 要清楚,由于您在问题中误解了,以下语法实际上是在JavaScript中。

 var re = new RegExp("'?" + "farmers".split("").join("'?") + "'?", "i") 

这样做是把你的输入字符串"farmers"分成一个单独的字符列表。

 "farmers".split("") == [ 'f', 'a', 'r', 'm', 'e', 'r', 's' ] 

然后用"'?"将字符重新拼接在一起"'?" 它们之间。 在正则表达式中,这意味着'字符将是可选的。 我将相同的粒子添加到表达式的开头和结尾,以匹配字符串的开头和结尾。

这将创建一个与您描述的方式匹配的正则表达式,前提是它也可以匹配原始字符串。

在这种情况下,上面的行构建了这个正则表达式:

 /'?f'?a'?r'?m'?e'?r'?s'?/ 

编辑

看了一下,以及你正在使用的function,我认为你最好的选择是修改高亮function以使用正则表达式而不是直接替换字符串。 我认为它甚至难以处理。 这是一个完全未经测试的刺。

 function innerHighlight(node, pat) { var skip = 0; if (node.nodeType == 3) { var matchResult = pat.exec(node.data); // exec the regex instead of toUpperCase-ing the string var pos = matchResult !== null ? matchResult.index : -1; // index is the location of where the matching text is found if (pos >= 0) { var spannode = document.createElement('span'); spannode.className = 'highlight'; var middlebit = node.splitText(pos); var endbit = middlebit.splitText(matchResult[0].length); // matchResult[0] is the last matching characters. var middleclone = middlebit.cloneNode(true); spannode.appendChild(middleclone); middlebit.parentNode.replaceChild(spannode, middlebit); skip = 1; } } else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { for (var i = 0; i < node.childNodes.length; ++i) { i += innerHighlight(node.childNodes[i], pat); } } return skip; } 

我在这里尝试做的是保留现有逻辑,但使用我构建的正则表达式来查找和拆分字符串。 请注意,我不再执行toUpper调用了,但是我已经使正则表达式不区分大小写了。 如上所述,我根本没有对此进行测试,但似乎它应该非常接近一个可行的解决方案。 无论如何足够让你入门。

请注意 ,这不会为您提供隐藏的字段。 我不确定你需要的是什么,但这会(如果它是正确的)照顾突出显示字符串。