正则表达式只替换一个匹配项

Regular expression replace only one matching

我在JavaScript

中有一个正则表达式代码
const regexns = /[A-Za-z]\:[A-Za-z]/gi;
data = data.replace(regexns, '__NS__');

如果我申请这个XML

<AnchorPane prefHeight="400.0" prefWidth="600.0"
    xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
    fx:controller="com.zigma.Controller">

我明白了

<AnchorPane prefHeight="400.0" prefWidth="600.0"
    xmlns="http://javafx.com/javafx/8" xmln__NS__x="http://javafx.com/fxml/1"
    f__NS__ontroller="com.zigma.Controller">

这意味着我在 :

的前后各放了 1 个字母

如何在不丢失那些边字母的情况下替换 :
正则表达式本身是否有任何选项,或者我们需要做循环和条件并像那样拆分?

预期输出为

<AnchorPane prefHeight="400.0" prefWidth="600.0"
    xmlns="http://javafx.com/javafx/8" xmlns__NS__fx="http://javafx.com/fxml/1"
    fx__NS__controller="com.zigma.Controller">

捕获 : 之前的字母,以便将其添加到替换中,并向前查找 : 之后的字母,这样它就不会被匹配。另请注意,由于您使用的是 case-insensitive 标志,因此无需重复 [A-Za-z],并且无需转义冒号:

const data = `<AnchorPane prefHeight="400.0" prefWidth="600.0"
    xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
    fx:controller="com.zigma.Controller">
    `;
console.log(data.replace(/([a-z]):(?=[a-z])/gi, '__NS__'));

根据您输入的形状,您可以改为使用单词边界:

const data = `<AnchorPane prefHeight="400.0" prefWidth="600.0"
    xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
    fx:controller="com.zigma.Controller">
    `;
console.log(data.replace(/\b:\b/gi, '__NS__'));

对于更强大的东西,我建议将字符串解析为 XML 文档,然后遍历文档的元素,将包含 : 模式的属性替换为新的属性。