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

Javascript和正则表达式:拆分字符串并保留分隔符,javascript,regex,Javascript,Regex,我有一个字符串: var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc" var string=“aaaaaa&dagger;bbbb&dagger;cccc” 我想用分隔符和一个特殊字符来分割这个字符串 为此,我使用以下方法: string.split(/<br \/>&#?[a-zA-Z0-9]+;/g); string.split(/&#?[a-zA-Z0-9]

我有一个字符串:

var string = "aaaaaa<br />&dagger; bbbb<br />&Dagger; cccc"
var string=“aaaaaa
&dagger;bbbb
&dagger;cccc”
我想用分隔符

和一个特殊字符来分割这个字符串

为此,我使用以下方法:

string.split(/<br \/>&#?[a-zA-Z0-9]+;/g);
string.split(/&#?[a-zA-Z0-9]+;/g);
我得到了我所需要的,只是我丢失了分隔符。 以下是一个例子:

如何保留分隔符?

使用,以便正则表达式断言特殊字符存在,但实际不匹配:

string.split(/<br \/>(?=&#?[a-zA-Z0-9]+;)/g);
string.split(/(?=&#?[a-zA-Z0-9]+)/g);
在行动中看到它:

var string=“aaaaaa
&dagger;bbbb
&dagger;cccc”;
console.log(string.split(/(?=&#?[a-zA-Z0-9]+)/g))如果将分隔符包装在parantesse中,它将成为返回数组的一部分

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

有一个好方法。

一个扩展函数用substring或RegEx分割字符串,并根据前面或后面的第二个参数放置分隔符

    String.prototype.splitKeep = function (splitter, ahead) {
        var self = this;
        var result = [];
        if (splitter != '') {
            var matches = [];
            // Getting mached value and its index
            var replaceName = splitter instanceof RegExp ? "replace" : "replaceAll";
            var r = self[replaceName](splitter, function (m, i, e) {
                matches.push({ value: m, index: i });
                return getSubst(m);
            });
            // Finds split substrings
            var lastIndex = 0;
            for (var i = 0; i < matches.length; i++) {
                var m = matches[i];
                var nextIndex = ahead == true ? m.index : m.index + m.value.length;
                if (nextIndex != lastIndex) {
                    var part = self.substring(lastIndex, nextIndex);
                    result.push(part);
                    lastIndex = nextIndex;
                }
            };
            if (lastIndex < self.length) {
                var part = self.substring(lastIndex, self.length);
                result.push(part);
            };
            // Substitution of matched string
            function getSubst(value) {
                var substChar = value[0] == '0' ? '1' : '0';
                var subst = '';
                for (var i = 0; i < value.length; i++) {
                    subst += substChar;
                }
                return subst;
            };
        }
        else {
            result.add(self);
        };
        return result;
    };

我遇到了相似但略有不同的问题。无论如何,这里有三种不同情况的示例,说明在何处放置除沫器

“1、2、3”。拆分(、)=[“1”、“2”、“3”]
“1、2、3”。拆分(/(、)/g)=[“1”、“2”、“3”]
“1、2、3”。拆分(/(?=、)/g)=[“1”、“2”、“3”]
“1、2、3”。拆分(/(?!))/g)=[“1”、“2”、“3”]
“1、2、3”。拆分(/(.*?)、/g)=[”、“1”、“1”、“2”、“3”]
警告:第四个字符只能拆分单个字符。提出:

//拆分路径,但保留目录后面的斜杠
var str='Animation/rawr/javascript.js';
var tokens=str.match(/[^\/]+\/?\\//g);
我一直在使用这个:

string.split(/<br \/>&#?[a-zA-Z0-9]+;/g);
String.prototype.splitBy=函数(分隔符){
变量
delimiterPATTERN='('+分隔符+'),
delimiterRE=newregexp(delimiterPATTERN,'g');
返回此.split(delimiterRE).reduce((块,项)=>{
如果(项匹配(分隔符)){
chunks.push(项目)
}否则{
chunks[chunks.length-1]+=项
};
返回块
}, [])
}
除了不应该弄乱
String.prototype
,这里有一个函数版本:

var splitBy=函数(文本,分隔符){
变量
delimiterPATTERN='('+分隔符+'),
delimiterRE=newregexp(delimiterPATTERN,'g');
返回text.split(delimiterRE).reduce(函数(块,项){
如果(项匹配(分隔符)){
chunks.push(项目)
}否则{
chunks[chunks.length-1]+=项
};
返回块
}, [])
}
所以你可以做:

var haystack=“aaaaaa
&dagger;bbbb
&dagger;cccc” 变压针=“和#?[a-zA-Z0-9]+”; var结果=splitBy(草堆、针) log(JSON.stringify(result,null,2))
你最终会得到:

[
“
&dagger;bbbb”, “
&Dagger;cccc” ]
在这里也回答了这个问题

在正则表达式中使用(?=模式)先行模式 范例

这将为您提供以下结果

[ '500x500', '-11', '*90', '~1', '+1' ]
也可以直接拆分

string = string.split(/(?=[$-/:-?{-~!"^_`\[\]])/gi);
给出相同的结果

[ '500x500', '-11', '*90', '~1', '+1' ]

我对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;
};
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);
    }
};

我也提出了这个解决方案。不需要正则表达式,非常可读

const str=“你好,世界,今天是多么美好的一天啊,巴尔布拉”
常量分隔索引=str.indexOf(“大”)
const parsedString=str.slice(分隔索引)

log(parsedString)
如果您事先知道分隔符,为什么不直接<代码>var delim=“
?谢谢@SIGANTEG,我知道预先使用的分隔符,但我无法使其适用于我的示例。我需要保持分隔符后面紧跟着特殊字符,因为有时我可以让一个
后面不跟特殊字符,而这个字符不必拆分。好问题,我有一个类似的情况,知道分隔符没有帮助。我在“]&[”上拆分。所以实际上我的分隔符是“&”但是分割不够精确,我需要让两边的括号来确定正确的分割。但是,我需要把这些括号放回分割字符串中。每边各1个。更妙的是,我不知道我们只能保留分隔符的一部分。事实上,我只需要保留特殊字符,我可以用这个:string.spl它(/(&#?[a-zA-Z0-9]+)/g);您可以通过忽略单词的大小写来优化表达式。或者匹配预定义的字符类。我将更新我的答案。为什么这么低。它完美且灵活这当然是最简单的方法,也是最可读的语法。我正在寻找类似于第三个示例的内容,但这仅适用于元素只有一个字符的情况ter-否则它将拆分为单独的字符。我最后不得不走一条乏味的路线。我不明白为什么每个人都在使用/gHow会使用这个正则表达式“1、2、3”。拆分(/(?!)/g)==[“1”、“2”、“3”]表示完整的单词?例如“foo1、foo2、foo3,”你真是个天才!你在哪里找到了解释其工作方式的文档?你不需要
g
a
.match
非贪婪的解决方案,例如:
“11、22、33”。match(/.*、|.++$/g)
->
[“11”、“22”、“33”]
。注意
/g
修饰符对匹配至关重要。为什么不立即拆分,就像Jon接受的答案一样?@Gordon…:)我可以这样做…更新代码…干杯当我使用此代码时,它会在每条字符串的末尾添加一个
0
。我在你给出的链接中找不到任何关于正向前瞻的内容。@PaulJones在中间时间被移动了。谢谢
[ '500x500', '-11', '*90', '~1', '+1' ]
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;
};
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);
    }
};
str = "first1-second2-third3-last";

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

str.splitAndKeep("-") == ["first1", "-", "second2", "-", "third3", "-", "last"];