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

标签 c# javascript jquery regex

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

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

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

这是该插件中的代码:

/*

highlight v4

Highlights arbitrary terms.

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

MIT license.

Johann Burkard
<http://johannburkard.de>
<mailto:jb@eaio.com>

*/

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”一词的所有实例...(续)

<div id="#myDiv">Farmers farm at Farmer's Market</div>

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

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

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

没问题,但我希望它使用这个:

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

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

  • “农民”
  • F'armers
  • 农民
  • 农民
  • 农民
  • 农民
  • 农民的
  • 农民

两个或多个撇号并排出现的情况,例如“Fa''rmers”,当然不应突出显示。

我想如果我能包含(要突出显示)“Fa'rmer's”这样的词就好了,但我不会碰运气,而且我会做得很好,只是为了获得像我的上面的项目符号列表,其中字符串中只出现一个撇号。

我考虑过正则表达式,但我不太了解语法,更不用说我认为我不能用 true/false 返回值做任何事情。

有什么办法可以完成我在这里需要的事情吗?

您可能想知道的事情:

  1. 突出显示插件可以满足我需要的所有不区分大小写的要求,因此根本无需担心这一点。
  2. 考虑到我在客户端使用的隐藏输入字段的值是通过我的 C# 代码在服务器端填充的,JavaScript、jQuery 甚至 C# 中提供的语法都是可以接受的。
  3. 填充隐藏输入字段的 C# 代码使用 Razor(即,我处于带有 WebMatrix 环境的 C#.Net 网页中。但是,此代码非常简单,如下所示:

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

    {

    <input class="highlightTerm" type="hidden" value="@searchTermsArray[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 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 调用,而是使正则表达式不区分大小写。如前所述,我根本没有对此进行测试,但看起来它应该非常接近可行的解决方案。无论如何,足以让您开始。

请注意,这不会让您获得隐藏字段。我不确定您需要这些做什么,但这将(如果正确的话)负责突出显示该字符串。

关于c# - 如何匹配并返回字符串的多个实例,其中任何索引中都可以包含单个撇号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19734758/

相关文章:

c# - 创建枚举后销毁 EnumBuilder?

c# - .NET 中是否存在指针?

javascript - 什么可能导致片段着色器中的纹理变黑?

javascript - TypeORM 与除 id 之外的字段的关系

javascript - jQuery aToolTip 插件只适用于链接的标题,我如何让它也适用于图像、字段和跨度的标题?

javascript - 获取 HTML5 视频,在页面加载时播放一次,然后淡出

javascript - 使用 JS onclick 使特定表格范围的内容可编辑

c# - 如何以编程方式提取应用名称和版本号?

c# - 如何制作流式 LINQ 表达式来传递过滤掉的项目以及过滤后的项目?

javascript - ReactNative null 不是一个对象(评估 'this.state.dataSource' )