Javascript和正则表达式:拆分字符串并保留分隔符

Mil*_*loš 105 javascript regex

我有一个字符串:

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc"
Run Code Online (Sandbox Code Playgroud)

我想用分隔符<br />和一个特殊字符分割这个字符串.

为此,我使用这个:

string.split(/<br \/>&#?[a-zA-Z0-9]+;/g);
Run Code Online (Sandbox Code Playgroud)

我得到了我需要的东西,除了我丢失了分隔符.这是一个例子:http://jsfiddle.net/JwrZ6/1/

我怎样才能保留分隔符?

jic*_*chi 145

我有类似但略有不同的问题.无论如何,这里是三个不同场景的例子,用于保持分隔符的位置.

"1?2?3".split("?") == ["1", "2", "3"]
"1?2?3".split(/(?)/g) == ["1", "?", "2", "?", "3"]
"1?2?3".split(/(?=?)/g) == ["1", "?2", "?3"]
"1?2?3".split(/(?!?)/g) == ["1?", "2?", "3"]
"1?2?3".split(/(.*??)/g) == ["", "1?", "", "2?", "3"]
Run Code Online (Sandbox Code Playgroud)

警告:第四个只能分割单个字符.ConnorsFan提出了另一种选择:

// Split a path, but keep the slashes that follow directories
var str = 'Animation/rawr/javascript.js';
var tokens = str.match(/[^\/]+\/?|\//g);
Run Code Online (Sandbox Code Playgroud)

  • 我正在寻找类似于第三个例子的东西,但这只有在元素只有一个字符的情况下才有效 - 否则会分成单个字符.我不得不最后去繁琐的[RegExp.exe](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec)路线. (3认同)
  • 我不明白为什么每个人都在使用/ g (2认同)
  • 如何使用这个正则表达式 "1、2、3".split(/(?!、)/g) == ["1、", "2、", "3"] 来表示完整单词?例如“foo1、foo2、foo3” (2认同)
  • 这些示例的`.match`非贪婪解决方案的翻译:`"11、22、33".match(/.*?、|.+$/g)` -&gt; `["11、", "22 、", "33"]`。注意 `/g` 修饰符对于匹配至关重要。 (2认同)

Jon*_*Jon 94

使用正向前瞻,以便正则表达式声明特殊字符存在,但实际上不匹配它:

string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g);
Run Code Online (Sandbox Code Playgroud)

看到它的实际效果:

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc";
console.log(string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g));
Run Code Online (Sandbox Code Playgroud)

更新:修复错字(;在前瞻性内容中移动文字)

  • 我在您提供的链接中找不到任何有关积极前瞻的信息。 (2认同)
  • 当我回到这个问题时,为自己发表评论:“积极”前瞻是“(?=)” (2认同)

Tor*_*ter 45

如果将分隔符包装在parantheses中,它将成为返回数组的一部分.

string.split(/(<br \/>&#?[a-zA-Z0-9]+);/g);
// returns ["aaaaaa", "<br />&dagger;", "bbbb", "<br />&Dagger;", "cccc"]
Run Code Online (Sandbox Code Playgroud)

根据您要保留的部分,更改您匹配的子组

string.split(/(<br \/>)&#?[a-zA-Z0-9]+;/g);
// returns ["aaaaaa", "<br />", "bbbb", "<br />", "cccc"]
Run Code Online (Sandbox Code Playgroud)

您可以通过忽略字母string.split(/()&#?[a-z0-9] +;/gi)的大小写来改进表达式.

您可以匹配预定义的组,如下所示:\dequals [0-9]\wequals [a-zA-Z0-9_].这意味着您的表达式可能如下所示.

string.split(/<br \/>(&#?[a-z\d]+;)/gi);
Run Code Online (Sandbox Code Playgroud)

JavaScriptKit上有一个很好的正则表达式参考.

  • 这当然是最简单的方法,也是最易读的语法。 (3认同)
  • 更好的是,我不知道我们只能保留分界符的一部分.实际上我只需要保留特殊字符,我可以用它来做:string.split(/ <br \/>(&#?[a-zA-Z0-9] +;)/ g); (2认同)
  • 为什么这么低..它完美且灵活 (2认同)

snn*_*snn 6

如果对分割模式进行分组,其匹配将保留在输出中,这是设计使然:

如果分隔符是带有捕获括号的正则表达式,则每次分隔符匹配时,捕获括号的结果(包括任何未定义的结果)都会拼接到输出数组中。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split#description

除非您的搜索模式使用前瞻或全局标志,否则您不需要。

const str = `How much wood would a woodchuck chuck, if a woodchuck could chuck wood?`

const result = str.split(/(\s+)/);
console.log(result);

// We can verify the result
const isSame = result.join('') === str;
console.log({ isSame });
Run Code Online (Sandbox Code Playgroud)

您可以使用多个组。您可以随心所欲地发挥创意,组之外的内容将被删除:

const str = `How much wood would a woodchuck chuck, if a woodchuck could chuck wood?`

const result = str.split(/(\s+)(\w{1,2})\w+/);
console.log(result, result.join(''));
Run Code Online (Sandbox Code Playgroud)


Fry*_*Fry 5

在这里也回答了 JavaScript 拆分正则表达式保留分隔符

在正则表达式示例中使用 (?=pattern) 前瞻模式

var string = '500x500-11*90~1+1';
string = string.replace(/(?=[$-/:-?{-~!"^_`\[\]])/gi, ",");
string = string.split(",");
Run Code Online (Sandbox Code Playgroud)

这将为您提供以下结果。

[ '500x500', '-11', '*90', '~1', '+1' ]
Run Code Online (Sandbox Code Playgroud)

也可以直接拆分

string = string.split(/(?=[$-/:-?{-~!"^_`\[\]])/gi);
Run Code Online (Sandbox Code Playgroud)

给出相同的结果

[ '500x500', '-11', '*90', '~1', '+1' ]
Run Code Online (Sandbox Code Playgroud)


Swi*_*Pro 5

我对 jichi 的答案进行了修改,并将其放入也支持多个字母的函数中。

String.prototype.splitAndKeep = function(separator, method='seperate'){
    var str = this;
    if(method == 'seperate'){
        str = str.split(new RegExp(`(${separator})`, 'g'));
    }else if(method == 'infront'){
        str = str.split(new RegExp(`(?=${separator})`, 'g'));
    }else if(method == 'behind'){
        str = str.split(new RegExp(`(.*?${separator})`, 'g'));
        str = str.filter(function(el){return el !== "";});
    }
    return str;
};
Run Code Online (Sandbox Code Playgroud)

jichi的答案第三种方法在这个函数中不起作用,所以我采用了第四种方法,并删除了空格以获得相同的结果。

编辑:第二种方法,除了数组来分割 char1 或 char2

String.prototype.splitAndKeep = function(separator, method='seperate'){
    var str = this;
    function splitAndKeep(str, separator, method='seperate'){
        if(method == 'seperate'){
            str = str.split(new RegExp(`(${separator})`, 'g'));
        }else if(method == 'infront'){
            str = str.split(new RegExp(`(?=${separator})`, 'g'));
        }else if(method == 'behind'){
            str = str.split(new RegExp(`(.*?${separator})`, 'g'));
            str = str.filter(function(el){return el !== "";});
        }
        return str;
    }
    if(Array.isArray(separator)){
        var parts = splitAndKeep(str, separator[0], method);
        for(var i = 1; i < separator.length; i++){
            var partsTemp = parts;
            parts = [];
            for(var p = 0; p < partsTemp.length; p++){
                parts = parts.concat(splitAndKeep(partsTemp[p], separator[i], method));
            }
        }
        return parts;
    }else{
        return splitAndKeep(str, separator, method);
    }
};
Run Code Online (Sandbox Code Playgroud)

用法:

str = "first1-second2-third3-last";

str.splitAndKeep(["1", "2", "3"]) == ["first", "1", "-second", "2", "-third", "3", "-last"];

str.splitAndKeep("-") == ["first1", "-", "second2", "-", "third3", "-", "last"];
Run Code Online (Sandbox Code Playgroud)


jor*_*iki 5

大多数现有答案早于 2018 年在 JavaScript 中引入后向断言。您没有指定希望如何将分隔符包含在结果中。一种典型的用例是用标点符号 ([.?!]) 分隔的句子,其中人们希望分隔符包含在结果字符串的末尾。这对应于已接受答案中的第四种情况,但正如那里所指出的,该解决方案仅适用于单个字符。末尾附加分隔符的任意字符串可以通过后向断言形成:

'It is. Is it? It is!'.split(/(?<=[.?!])/)
/* [ 'It is.', ' Is it?', ' It is!' ] */
Run Code Online (Sandbox Code Playgroud)