【问题标题】:Split string by occurrences character按出现字符拆分字符串
【发布时间】:2019-04-05 15:05:05
【问题描述】:

我正在尝试编写一个正则表达式以在 split() 函数中使用,以便按照以下规则拆分字符串:

  1. 如果找到\,则在\ 之前和\ 之后的字符之后进行拆分(例如"Hel\\7o".split()["Hel", "\7", "o"]
  2. 如果找到%,我们有类似的行为,但我只接受字母。 (例如"He%7l%lo".split()["He%7l", "%l", "o"]
  3. 如果""'' 之间有字符串,则将它们拆分(例如"Hel\"lo\"".split()["Hel", ""lo""];
  4. 如果找到,或:,或/,我们将拆分(例如"Hel/lo Wor:ld".split()["Hel", "/", "lo", " ", "Wor", ":", "ld"]

到目前为止,我已经使用以下正则表达式完成了我所说的:/(\\.|%[a-zA-Z]|\".*\"|\'.*\'|:|\/| )/

现在,我需要最后一个拆分规则,即我需要将一个 char 的出现与其他 char 的出现分开。基本上,如果我有"mmDD",我希望有["mm", "DD"]
当然,到目前为止,这需要与所有其他规则一起使用,因此 "mm mmDDYYy%y" 将返回 ["mm", " ", "mm", "DD", "YY", "y", "%y"]
在最后一个示例中,您还可以看到最后一个规则需要区分大小写("YY""y" 分离)。

我找到了这个答案 -> JavaScript Split string by multiple occurrences of letters 但它对我没有帮助,因为它丢失了出现的次数(例如 "mmDD".split(/(.)\1*/) 返回 ["m","D"],但我需要 ["mm","DD"]

我基本上尝试过使用所有正则表达式规则,但在此之后我失去了理智。甚至可以直接使用split() 函数吗?

感谢您的帮助。

编辑:如果有帮助,这里是 regex101 链接https://regex101.com/r/ezXKkG/1/

另外,Wiktor Stribiżew 建议(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[a-z])),我在全局规则中添加了如下:/(\\.|%[a-zA-Z]|\".*\"|\'.*\'|:|\/| |(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[a-z]))/

这样,"MMmm" 被拆分为 ["MM", "mm"](很好!),但它在以下情况下不起作用:"MMmdD",它被拆分为 ["MM", "md", "D"]

【问题讨论】:

  • "Hel\7o" 中没有文字 \,你的意思是写 "Hel\\7o" 吗?还是要搜索控制字符?
  • 是的,抱歉,我注意到问题中有一些错误,没有空格的字符太多:S 我正在纠正它。编辑:现在应该没问题了
  • 我不完全确定这可以通过 JavaScript 中的正则表达式实现。使用lookbehinds应该是可行的,但那些不是标准的。甚至 with 后视,正则表达式也会相当难看,因为每个规则都需要多个条件,并且还需要为规则分支。所以你至少有 8 个分支(4 个规则 * 每个 2 个条件),这很快就会变得难以阅读和维护。
  • 我只是感谢您的努力,并给其他人一个提示。老实说,我不知道这是否“不可能”,这就是我添加您的部分解决方案的原因
  • 可能有一些问题,但试试看str.split(/(\\.|%[a-zA-Z]|\".*\"|\'.*\'|:|\/| |(.)\2+)/).filter(Boolean).filter((w,i,a) => !(a[i-1] !== void 0 && a[i-1].length > w.length && a[i-1][0] === w[0]));

标签: javascript regex


【解决方案1】:

最后,我设法解决问题的唯一方法是将我的目标一分为二:

  1. 使用类似于我第一次提到的正则表达式 (/(\\.|%[a-zA-Z]|\"[^"]*\"|\'[^']*\'|:|\/| +|\w+)/),我按照我需要的前四个规则拆分字符串;
  2. 为了实现第五条也是最后一条规则,我运行以下代码:

    tokens = toSplit.split(/(\\.|%[a-zA-Z]|\".*\"|\'.*\'|:|\/| )/);
    tokens.forEach(token => {
        if (/^[a-zA-Z]$/).test(token) {
            let newToken = '';
    
            for (let i = 0, len = token.length; i < len; i++) {
                const tokenChar = token[i];
                const lastChar = newToken[newToken.length - 1];
                if (lastChar && lastChar !== tokenChar) {
                    // saving newToken
                    newToken= '';
                }
    
                newToken+= tokenChar;
            }
        }
    )}
    

基本上,对于我使用正则表达式检索到的每个字符串,我都会检查它是否仅由字符组成。如果是这样,我手动将字符串拆分为不同的子字符串迭代。

我知道这个答案并不能解决仅在split 函数中使用正则表达式的问题,但到目前为止我还没有找到任何其他解决方案。至少这个有效,其他人可能会发现它有用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多