【问题标题】:Split on capitalized words not between underscores拆分不在下划线之间的大写单词
【发布时间】:2023-04-07 22:53:01
【问题描述】:

给定以下字符串:ThisIsA_SimpleTest_Case

我想分割所有大写单词而不是下划线之间的字符串以及下划线之间的字符串的第一个下划线。

预期的拆分结果:这是一个SimpleTest案例

我想出了以下不工作的正则表达式,用于 Java 正则表达式风格:

(?=_[a-zA-Z]*_|[A-Z])

但这当然行不通,因为它是 or 而不是 and。此外,这会拆分下划线内的所有大写单词,这是我想忽略的。

【问题讨论】:

  • 看来你应该匹配,比如_[^_]*_|(?<![A-Z])[A-Z][a-z]*
  • 我想分割所有大写的单词而不是在下划线之间和在下划线之间的字符串的第一个下划线。令人困惑!你能再改一下吗?
  • 下划线可以有多对吗?还是最多一个?

标签: java regex regex-lookarounds


【解决方案1】:

拆分前的另一种做法:

字符串在拆分前改变,见上下文:

public static void main(String[] args) {
    String input = "ThisIsA_SimpleTest_Case";
    String inputReplace1 =  input.replaceAll("_(\\w+[a-z])([A-Z]\\w+)_", ",$1#$2");
    String inputReplace2 = inputReplace1.replaceAll("(?<=[a-z])(?=[A-Z])", ",");
    String inputReplace3 = inputReplace2.replaceAll("#", "");
    System.out.println(Arrays.asList(inputReplace3.split(",")));
}

输出:

[This, Is, A, SimpleTest, Case]

【讨论】:

    【解决方案2】:

    你可能会分手:

    (?=(?<!_)[A-Z](?![A-Za-z]*_))|(?<!_[A-Za-z]{0,1000}|^)(?=[A-Z])|_
    
    • (?=(?&lt;!_)[A-Z](?![A-Za-z]*_)) 如果它是一个字符 A-Z 没有直接在 _ 前面并且右侧没有 _ 的位置
    • |或者
    • (?&lt;!_[A-Za-z]{0,1000}|^)(?=[A-Z])如果是左边不是下划线或字符串开头的位置,而右边是char A-Z
    • |或者
    • _ 匹配下划线

    Regex demo | Java demo

    示例代码

    String regex = "(?=(?<!_)[A-Z](?![A-Za-z]*_))|(?<!_[A-Za-z]{0,1000}|^)(?=[A-Z])|_";
    String str = "ThisIsA_SimpleTest_Case";
    String[] parts = str.split(regex);
    
    for (String part : parts)
        System.out.println(part);
    

    输出

    This
    Is
    A
    SimpleTest
    Case
    

    【讨论】:

      【解决方案3】:

      Wiktor 是对的,尝试匹配应该更容易,而不是分裂你不想要的东西。

      但是因为这是一个有趣的挑战,所以我得到了一个可以按照你想要的方式拆分它的挑战。 _|(?&lt;!_)(?=[A-Z])(?=[^_]*(?:_[^_]*_[^_]*)*[^_]*$)

      也适用于多对下划线。 (当然可以改进,我可能会尝试简化它)

      这个想法是:

      • _| 拆分任何下划线,将其从最终列表中删除。
      • (?&lt;!_) 不是在下划线之后。如果你不这样做,你可能会在拆分后得到空匹配(_| 已经处理的情况)。不介意的可以跳过。
      • (?=[A-Z]) 在大写字母前拆分。
      • (?=[^_]*(?:_[^_]*_[^_]*)*[^_]*$) 但后面必须跟偶数个下划线。如果有一个奇数,这意味着你在 2 之间,它不应该分裂。我假设字符串中不能有奇数个下划线。

      https://regex101.com/r/Iov1Yl/1/测试

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-24
        • 1970-01-01
        • 2012-04-28
        • 1970-01-01
        • 2016-04-25
        • 2017-08-08
        相关资源
        最近更新 更多