用同一行开头的匹配替换一行上的所有斜杠

Posted

技术标签:

【中文标题】用同一行开头的匹配替换一行上的所有斜杠【英文标题】:Replace all slashes on a line with a match on at the beginning of the same line 【发布时间】:2019-05-23 02:47:43 【问题描述】:

我正在尝试更改一行上的所有斜杠以替换为每行开头的 3 个字符块。 (以下示例中的 PMC、PAJ 等)

.PMC.89569XX/90051XX/90204XX/89533XX/90554XX/90053XX/90215XX/89874XX/89974XX/90481XX/90221XX/90508XX/90183XX/88526XX/89843XX/88041XX/09 /89847XX/88616XX/90513XX/90015XX/90334XX/89649XX.T00 .PAJ.77998XX/77896XX.T00 .PAG.78116XX/78104XX/77682XX/07616XX/77663XX/77863XX/07634XX/78088XX/77746XX/78148XX.T00 。 PKC 强> .22762xx / 22358xx / 22055xx / 22672xx / 22684xx / 22154xx / 22608xx / 22768xx / 22632xx / 22266xx / 22714xx / 22658xx / 22631xx / 22288xx / 22020xx / 22735xx / 22269xx / 22138xx / 22331xx / 22387xx / 22070XX/22636XX/22629XX/22487XX/22725XX.T00

期望的结果应该是:

PMC.89569XXPMC90051XXPMC90204XXPMC89533XXPMC90554XXPMC90053XXPMC90215XXPMC89874XXPMC89974XXPMC90481XXPMC90221XXPMC90508XXPMC90183XXPMC88526XXPMC89843XXPMC88041XXPMC90446XXPMC88515XXPMC89574XXPMC89847XXPMC88616XXPMC90513XXPMC90015XXPMC90334XXPMC89649XX.T00 P>

我不确定如何做到这一点。 这是我目前所拥有的:

 (.)([A-Z]3)(.)(\/)

【问题讨论】:

您还想删除每行的第一个点吗? 最后是的,第二个点也是如此 您只能使用正则表达式,但只能使用符合 ECMAScript2018 的正则表达式。 【参考方案1】:

如果您只计划支持 ECMAScript 2018 及更高版本,您可以使用单个正则表达式来实现您的需求:

.replace(/(?<=^\.([^.]+)\..*?)\//g, "$1")

请参阅regex demo。

详情

(?&lt;=^\.([^.]+)\..*?) - 一个积极的向后看,紧靠当前位置的左侧,需要 ^ - 字符串开头 \. - 一个点 ([^.]+) - 第 1 组:一个或多个除点以外的字符 \. - 一个点 .*? - 任何 0+ 字符,除了换行符,尽可能少 \/ - / 字符。

JS 演示:

var strs = ['.PMC.89569XX/90051XX/90204XX/89533XX/90554XX/90053XX/90215XX/89874XX/89974XX/90481XX/90221XX/90508XX/90183XX/88526XX/89843XX/88041XX/90446XX/88515XX/89574XX/89847XX/88616XX/90513XX/90015XX/90334XX/89649XX.T00','.PAJ.77998XX/77896XX.T00','.PAG.78116XX/78104XX/77682XX/07616XX/77663XX/77863XX/07634XX/78088XX/77746XX/78148XX.T00','.PKC.22762XX/22358XX/22055XX/22672XX/22684XX/22154XX/22608XX/22768XX/22632XX/22266XX/22714XX/22658XX/22631XX/22288XX/22020XX/22735XX/22269XX/22138XX/22331XX/22387XX/22070XX/22636XX/22629XX/22487XX/22725XX.T00'];
for (var s of strs) 
 console.log(s.replace(/(?<=^\.([^.]+)\..*?)\//g, "$1"));

【讨论】:

感谢 Wiktor,这几乎可以解决问题。除了它只适用于第一行。 'PMC' 不能同时用于其他'PAJ' 等 @QAZ001 如果您必须为多行字符串运行它,请使用m 修饰符:s.replace(/(?&lt;=^\.([^.\n]+)\..*?)\//gm。如果有任何故障,请使用/(?&lt;=(?:^|\n)\.([^.]+)\..*?)\//g 几乎但仍然包含缺陷。它在 PAJ 之前工作正常。但是,它开始将 PAG 和 PKC 更改为 PAJ。 @QAZ001 actually works,您的字符串中的换行符有问题。找出它们并添加到(?:^|[\n\r]) 模式中。【参考方案2】:

我不确定您是否可以仅使用一个正则表达式来完成此操作,并且您可能必须分两步完成。首先,您可以使用substring() 方法捕获三个大写字母,然后您可以将所有斜杠替换为出现在第一个点之后字符开头的三个字母。这是一个带有JS代码的演示,

function transformLine(s) 
    var repStr = s.substring(1,4);
    var replacedStr = s.replace(/\//g, repStr);

    return replacedStr.substring(1,replacedStr.length);


var lines = [".PMC.89569XX/90051XX/90204XX/89533XX/90554XX/90053XX/90215XX/89874XX/89974XX/90481XX/90221XX/90508XX/90183XX/88526XX/89843XX/88041XX/90446XX/88515XX/89574XX/89847XX/88616XX/90513XX/90015XX/90334XX/89649XX.T00", ".PAJ.77998XX/77896XX.T00", ".PAG.78116XX/78104XX/77682XX/07616XX/77663XX/77863XX/07634XX/78088XX/77746XX/78148XX.T00", ".PKC.22762XX/22358XX/22055XX/22672XX/22684XX/22154XX/22608XX/22768XX/22632XX/22266XX/22714XX/22658XX/22631XX/22288XX/22020XX/22735XX/22269XX/22138XX/22331XX/22387XX/22070XX/22636XX/22629XX/22487XX/22725XX.T00"];

for (var i = 0;i<lines.length;i++) 
    console.log("Before: " + lines[i]);
    console.log("After: " + transformLine(lines[i])+"\n\n");

我已经替换了第一个点,因为您的预期输出没有它。

让我知道这是否适合你。

编辑:

我已更新代码以提供一个函数,该函数将字符串作为输入并返回修改后的字符串。请查看演示。

Edit2:主要使用正则表达式解决它

函数中的这一行为您完成了将行转换为所需行的所有工作。

function transformLine(s) 
    return s.replace(/\//g, /^.(.3)/.exec(s)[1]).replace(/^./,'');


var lines = [".PMC.89569XX/90051XX/90204XX/89533XX/90554XX/90053XX/90215XX/89874XX/89974XX/90481XX/90221XX/90508XX/90183XX/88526XX/89843XX/88041XX/90446XX/88515XX/89574XX/89847XX/88616XX/90513XX/90015XX/90334XX/89649XX.T00", ".PAJ.77998XX/77896XX.T00", ".PAG.78116XX/78104XX/77682XX/07616XX/77663XX/77863XX/07634XX/78088XX/77746XX/78148XX.T00", ".PKC.22762XX/22358XX/22055XX/22672XX/22684XX/22154XX/22608XX/22768XX/22632XX/22266XX/22714XX/22658XX/22631XX/22288XX/22020XX/22735XX/22269XX/22138XX/22331XX/22387XX/22070XX/22636XX/22629XX/22487XX/22725XX.T00"];

for (var i = 0;i<lines.length;i++) 
    console.log("Before: " + lines[i]);
    console.log("After: " + transformLine(lines[i])+"\n\n");

正如你在这里看到的,这条线,

return s.replace(/\//g, /^.(.3)/.exec(s)[1]).replace(/^./,'');

完成您需要的所有工作。它首先使用此/^.(.3)/.exec(s)[1] 提取三个大写字母,然后将所有斜杠替换为此捕获的单词,最后使用此/^./,'' 删除第一个点字符,最后返回您需要的字符串。

如果这是您想要的,请告诉我。否则,如果您以任何特定方式进一步想要它,请告诉我。

【讨论】:

我正在尝试更改每行开头的所有斜杠...但您的代码仅适用于一行 @Mohammad:我已经为一行演示了它,当然它可以用于任意数量的行。 我实际上是在寻找纯正则表达式的解决方案。如果需要多个步骤也没问题。 @QAZ001:用单个正则表达式来做这件事似乎是不可能的,因为首先你想捕获一个字符串,然后你想用这三个字符的单词替换任何出现的斜杠。 @Mohammad:我已经将我的代码包含在一个函数中,并通过一个字符串数组对所有行运行它。希望你也一样。

以上是关于用同一行开头的匹配替换一行上的所有斜杠的主要内容,如果未能解决你的问题,请参考以下文章

由于更多匹配,bash没有替换匹配字符串上的一行

用正则表达式替换某一区段内的字符,在线等

sed匹配全行,行首,行尾后替换或添加字符

在VSCode中用正则匹配文件每行的开头

在WPS中,第一行字数没满,怎么把第二行的合并上来,除了在第二行开头按Backspace之外

awk用法之:文本替换