【问题标题】:Regex, grab only one instance of each letter正则表达式,每个字母只抓取一个实例
【发布时间】:2011-06-15 00:30:09
【问题描述】:

我有一个段落被分成一个数组,在句点处分割。我想对 index[i] 执行一个正则表达式,用 index[i] 的字符串值具有的每个字母的一个实例替换它的内容。

所以; index[i]:"This is a sentence" 将返回 --> index[i]:"thisaenc"

我读过this thread。但我不确定这是否是我正在寻找的。​​p>

【问题讨论】:

  • 你用的是什么正则表达式? Javascript 不支持lookbehinds。
  • @agent-j - Jquery,添加了标签。
  • @Jason,这和 jQuery 有什么关系?
  • 严格来说,替换不仅仅是一个正则表达式。但是您应该指定您的语言,正则表达式引擎的怪癖和种类繁多。虽然你需要一个可变长度的负回溯,但我几乎可以肯定,或者找到一种解决方法。
  • 您只想要句子中出现的所有唯一字母吗?

标签: javascript regex


【解决方案1】:

不确定如何在正则表达式中执行此操作,但这里有一个非常简单的函数,无需使用正则表达式即可:

function charsInString(input) {
    var output='';
    for(var pos=0; pos<input.length; pos++) {
        char=input.charAt(pos).toLowerCase();
        if(output.indexOf(char) == -1 && char != ' ') {output+=char;}
    }
    return output;
}

alert(charsInString('This is a sentence'));

【讨论】:

  • 如果您像这样更改这两行:char=input.charAt(pos).toLowerCase(); if(output.indexOf(char) == -1 &amp;&amp; char != ' ') {output+=char;},它将给出所需的确切字符串。
  • @morja -- 是的,谢谢;我会编辑答案。 (我没有测试或检查就发布了它,因为就在我完成时,我看到@Jason 发布了他自己的答案!)
【解决方案2】:

由于我很确定使用单个正则表达式无法满足您的需求,因此我提供了一个更通用的解决方案:



// collapseSentences(ary) will collapse each sentence in ary 
// into a string containing its constituent chars
// @param  {Array}  the array of strings to collapse
// @return {Array}  the collapsed sentences
function collapseSentences(ary){
  var result=[];
  ary.forEach(function(line){
    var tmp={};
    line.toLowerCase().split('').forEach(function(c){
        if(c >= 'a' && c <= 'z') {
            tmp[c]++;
        }
    });
    result.push(Object.keys(tmp).join(''));
  });
  return result;
}

除了不能保证每个句子中的字符顺序保持不变之外,它应该做你想做的事情,尽管在大多数情况下是这样。

给定:

var index=['This is a sentence','This is a test','this is another test'],
    result=collapseSentences(index);

结果包含:

["thisaenc","thisae", "thisanoer"]

【讨论】:

    【解决方案3】:
    (\w)(?<!.*?\1)
    

    这会为每个正确的字符生成一个匹配项,但就好像您是从右到左阅读一样。 这会找到一个单词字符,然后向前查找刚刚匹配的字符。

    【讨论】:

    • 如果如前所述,JavaScript 不支持后视,这将如何在 OP 规定的环境中工作?
    • 这在什么正则表达式风格下起作用? Lookbehind 通常需要固定宽度,在您的情况下,它不会在任何东西后面寻找或实际上导致字符串被替换。
    • 我在他回答我对环境的要求之前回答了这个问题。不过,很好的收获。 :-)
    • 我想你可以使用积极的前瞻,然后用空字符串替换匹配项。
    【解决方案4】:

    没关系,我做到了:

    justC = "";
    if (color[i+1].match(/A/g)) {justC += " L_A";}
    if (color[i+1].match(/B/g)) {justC += " L_B";}
    if (color[i+1].match(/C/g)) {justC += " L_C";}
    if (color[i+1].match(/D/g)) {justC += " L_D";}
    if (color[i+1].match(/E/g)) {justC += " L_E";}
    else {color[i+1] = "L_F";}
    

    这并不是我的问题可能导致我相信我想要的,但这是我所追求的打印输出,用于课堂:&lt;span class="L_A L_C L_E"&gt;&lt;/span&gt;

    【讨论】:

    • 很高兴您找到了适合您的解决方案。我完全不知道这与这个问题有什么关系!
    • Err... match(/A/g) 将返回 'A' 在目标中出现的次数,而 match(/A/) 将返回 1 (true) 如果至少有一个 ' A'出现。丢失 /g 可显着提高性能。
    【解决方案5】:

    怎么样:

    var re = /(.)((.*?)\1)/g;
    var str = 'This is a sentence';
    x = str.toLowerCase();
    x = x.replace(/ /g, '');
    while(x.match(re)) {
        x=x.replace(re, '$1$3');
    }
    

    【讨论】:

      【解决方案6】:

      我认为这不能一举用正则表达式完成。您将需要使用循环。

      虽然我的示例不是用您选择的语言编写的,但它似乎没有使用 javascript 中不存在的任何正则表达式功能。

      perl -e '$foo="This is a sentence"; while ($foo =~ s/((.).*?)\2/$1/ig)  { print "<$1><$2><$foo>\n"; } print "$foo\n";'
      

      制作:

      This aenc
      

      【讨论】:

      • 为什么被否决了?它工作并使用正则表达式。
      猜你喜欢
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-31
      • 1970-01-01
      相关资源
      最近更新 更多