JavaScript 正则表达式替换多个字母

标签 javascript regex

我有以下代码用它的补码替换一串 DNA,其中 A <=> T 和 C <=> G。我用正则表达式的非常基本的知识来做到这一点。我如何使用正则表达式重构以下内容以捕获字母并将其替换为补码。

function DNA(strand) {
    return strand.replace(/A|T|C|G/g, x => {
        return (x=="A") ? "T" : (x=="T") ? "A" (x=="C") ? "G" : "C";
    });
}

最佳答案

IMO,这相当不优雅,但它是一个使用 javascript 正则表达式功能的一步(两步?)替换算法 - 如果您有兴趣,我可以解释它到底在做什么

function DNA(strand) {
    return strand
        .concat("||TACG")
        .replace(/A(?=.*?(T))|T(?=.*?(A))|C(?=.*?(G))|G(?=.*?(C))|\|\|....$/gi, "$1$2$3$4");
}

参见 this fiddle (现在针对可测试性进行了一些更新)来尝试一下。

这可能看起来像是构建正则表达式的简单示例,但实际上并非如此(如果您希望它全部在正则表达式中,那就是)。使用简单的映射表(哈希表)、拆分字符、重新映射/翻译它们并将它们连接在一起(就像@Jared Smith 所做的那样)会更有效率,因为正则表达式引擎效率不高。如果这仅仅是出于个人兴趣和学习正则表达式,那么请随时询问任何需要的解释。

为 jwco 编辑:

正如我所说,这对于生产级别的解决方案来说相当不优雅(或至少是低效的),但作为一件艺术品(?)可能相当优雅。它仅使用 JavaScript 正则表达式 (Regexp) 功能,因此没有“正则表达式条件”或“后视”,如果 JavaScript 支持“自由间距”,您实际上可以使用正则表达式 如下所示

这是分解正则表达式组件以解释每个部分匹配、查找和捕获的内容的一种相对常见的方法:

  A         #  Match an A, literally
  (?=       #  Look ahead, and
    .*?     #    Match any number of any character lazily (as necessary)
    (T)     #    Match and capture a T, literally (into group #1)
  )         #  End look-ahead
|           #-OR-
  T         #  Match a T, literally
  (?=       #  Look ahead, and
    .*?     #    Match any number of any character lazily (as necessary)
    (A)     #    Match and capture an A, literally (into group #2)
  )         #  End look-ahead
|           #-OR-
  C         #  Match a C, literally
  (?=       #  Look ahead, and
    .*?     #    Match any number of any character lazily (as necessary)
    (G)     #    Match and capture a G, literally (into group #3)
  )         #  End look-ahead
|           #-OR-
  G         #  Match a G, literally
  (?=       #  Look ahead, and
    .*?     #    Match any number of any character lazily (as necessary)
    (C)     #    Match and capture a C, literally (into group #4)
  )         #  End look-ahead
|           #-OR-
 \|\|....$  #  match two literal pipes (|), followed by four of any character and the end of the string

与此表达式匹配的任何内容(应该是整个字符串的每个部分)都将被替换表达式 $1$2$3$4 替换。 “全局”标志(/gi 中的 g)将使它不断尝试匹配,只要有更多的字符串要测试。

表达式由五个可能的选项组成(一个对应于每个可能的字母开关,然后是一个“清理”匹配项)。除了匹配的特定字母外,前四个选项是相同的。这些中的每一个都匹配并消耗一个特定的所需字母,然后在字符串中“向前看”以找到其“翻译”或“补充”,捕获它而不消耗任何其他内容,然后作为成功的替代完成, 从而满足整个表达式。

由于只有一个匹配组 (1-4) 可以匹配任何成功测试的字母,因此只有一个反向引用($1$1$2$3$4) 可能包含捕获的值。对于第五个选项 (\|\|....$),没有捕获,因此没有任何捕获组包含用于替换匹配项的值。

在被输入正则表达式引擎之前,字符串 ||TACG 被附加到源中,有点像端粒...... 有点...... - 这提供了一个替代品源,如果源字符串在较早的位置不包含适当的“补充”字母(或根本不包含?!)。正则表达式中的最后一个选项通过匹配并将其替换为任何内容,有效地删除了这些无关信息。

这可以用于任何一组替换,但随着附加的更改越来越多,效率会越来越低。这样一个正则表达式的可维护性也会,正如某个评论者(我希望是愉快的)威胁所指出的,嗯……这将是一个挑战。享受吧!

关于JavaScript 正则表达式替换多个字母,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33286142/

相关文章:

javascript - Vue 中传递事件方法

javascript - 带有小数位的 Math.Random 和 Javascript 中的代码错误

python的re : find words beginning from "string" in any case

node.js - 用逗号分隔的数组的正则表达式nodejs

php - 如何使用 preg_match 返回只需要的匹配

javascript - 单击按钮时 Angular 2/Typescript 删除对象

javascript - Backbone SPA : Best practice for loading new routes?

javascript - 从文本文件在 javascript 中创建下拉列表

c++ - 如何防止pcre(C库)在一个字符串失败时继续匹配?

c# - 正则表达式基于组的不同替换?