如何将连字符分隔的标签名称转换为驼峰式大小写

Biz*_*der 4 java regex string

我有一个像这样的字符串 -

<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>
Run Code Online (Sandbox Code Playgroud)

我想删除连字符 ( -) 并将每个删除的连字符后面的单个字母字符大写。即从连字符分隔的单词转换为“CamelCase”。

喜欢 -

<phoneResidence></phoneResidence><maritalStatus>1</maritalStatus><phoneOnRequest></phoneOnRequest>
Run Code Online (Sandbox Code Playgroud)

这个怎么做?

Jim*_*son 5

自 Java 8 函数接口以来,出现了一个String#replaceAll()采用转换函数来“动态”修改匹配子序列并构建最终输出的函数接口。

首先,警告:正则表达式对于解决某一类问题来说是非常棒的、非常强大的工具。在应用正则表达式之前,您必须确定问题是否可以解决。通常,处理 XML 是正则表达式问题的对立面,但在这种情况下,目标是将输入仅视为字符串而不是 XML。(但请仔细阅读下面的警告)

以下是 Jamie Zawinski 1997 年的一句名言:

有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。

解决方案

有了这些警告,这是您问题的代码:

    String input="<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>";
    Matcher m = Pattern.compile("-[a-zA-Z]").matcher(input);
    // Do all the replacements in one statement using the functional replaceAll()
    String result = m.replaceAll(s -> s.group().substring(1).toUpperCase());
Run Code Online (Sandbox Code Playgroud)

解释

正则表达式匹配单个连字符后跟任何单个字母字符(大写或小写)。使用扫描replaceAll()输入Matcher。在每次匹配时,它都会调用 lambda(具有单个apply()方法的匿名类的函数简写),传入String包含匹配文本的参数。然后,无论 lambda 返回什么,都会将其替换到该方法构建的输出字符串replaceAll()中,以代替匹配的字符串。

警告

上面给出的解决方案完全不了解 XML 的结构,它会更改任何-a组合(wherea代表任何字母)并将其替换为 just A(whereA代表大写字母),无论它出现在哪里。

在您给出的示例中,此模式仅出现在标签名称中。但是,如果文件的其他部分包含(或可以包含)该模式,那么这些实例也将被替换。如果该模式出现在文本数据中(即不在标签内部,而是在标签之间)或作为属性值出现,这可能会出现问题。这种盲目地将正则表达式应用于整个文件的方法是一种电锯方法。如果你真的真的需要一把电锯,你就使用它。

然而,如果事实证明电锯太强大并且您的实际任务需要更多技巧,那么您将需要切换到真正的 XML 解析器(JDK 包含一个很好的解析器),它可以处理所有微妙之处。它分别向您提供标签名称、属性名称、属性值、文本等各种语法片段,以便您可以明确决定哪些部分受到影响。您仍然可以使用replaceAll()上面的内容,但仅将其应用于需要的部分。

几乎作为一条规则,您绝对不会使用正则表达式来处理 XML,或解析包含嵌套或转义引号的字符串,或解析 CSV 或 TSV 文件。这些数据格式通常不适合使用正则表达式。