簡體   English   中英

如何將連字符分隔的標記名稱轉換為駝峰大小寫

[英]How to convert hyphen-delimited tag names to camel case

我有一個字符串 -

<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>

我想在每個刪除的連字符后刪除連字符( - )和大寫單字母字符。 即從連字符分隔的單詞轉換為“CamelCase”。

喜歡 -

<phoneResidence></phoneResidence><maritalStatus>1</maritalStatus><phoneOnRequest></phoneOnRequest>

這個怎么做?

實際上,這非常簡單。 只需讀取輸入字符串的每個字符,並使用boolean來決定是否應該按原樣添加字符,大寫或忽略():

public class Main {
    public static void main(String[] args) {
        String input = "<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>";
        StringBuilder output = new StringBuilder();
        boolean capitalizeNext = false;
        for (int i = 0; i < input.length(); i++) {
            char thisChar = input.charAt(i);
            if (thisChar == '-') {
                capitalizeNext = true;
            } else if (capitalizeNext) {
                output.append(String.valueOf(thisChar).toUpperCase());
                capitalizeNext = false;
            } else {
                output.append(thisChar);
                capitalizeNext = false;
            }
        }
        System.out.println(output.toString());
    }
}

輸出:

<phoneResidence></phoneResidence><maritalStatus>1</maritalStatus><phoneOnRequest></phoneOnRequest>


相同代碼附加評論:

 public class Main { public static void main(String[] args) { String input = "<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>"; StringBuilder output = new StringBuilder(); // This is used to determine if the next character should be capitalized boolean capitalizeNext = false; // Loop through each character of the input String for (int i = 0; i < input.length(); i++) { // Obtain the current character from the String char thisChar = input.charAt(i); if (thisChar == '-') { // If this character is a hyphen, set the capitalizeNext flag, but do NOT add this character to // the output string (ignore it) capitalizeNext = true; } else if (capitalizeNext) { // The last character was a hyphen, so capitalize this character and add it to the output string output.append(String.valueOf(thisChar).toUpperCase()); // Reset the boolean so we make a new determination on the next pass capitalizeNext = false; } else { // Just a regular character; add it to the output string as-is output.append(thisChar); // Reset the boolean so we make a new determination on the next pass capitalizeNext = false; } } // Just print the final output System.out.println(output.toString()); } } 

由於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());

說明

正則表達式匹配單個連字符后跟任何單個字母字符,大寫或小寫。 replaceAll()使用Matcher掃描輸入。 在每次匹配時,它調用lambda(帶有單個apply()方法的匿名類的功能簡寫)傳入包含匹配文本的String參數。 然后,無論lambda返回什么,都將替換為由replaceAll()方法構建的輸出字符串,而不是匹配的字符串。

警告

上面所給出的解決方案是完全失明到XML的結構會改變任何-a組合(其中a為任何字母表示)中並用只需更換它A (其中A代表一個大寫字母),不管在其中顯示。

在您給出的示例中,此模式僅在標記名稱中出現。 但是,如果文件的其他部分包含(或可以包含)該模式,那么這些實例也將被替換。 如果該模式出現在文本數據中(即不在內部,但標簽之間 )或作為屬性值則可能會出現問題。 盲目地將正則表達式應用於整個文件的方法是一種鏈鋸方法。 如果你真的需要電鋸,你就可以使用它。

但是,如果事實證明鏈鋸太強大而你的實際任務需要更多的技巧,那么你需要切換到真正的XML解析器(JDK包含一個好的解析器),它可以處理所有細微之處。 它分別為您提供各種語法位和部分,如標記名稱,屬性名稱,屬性值,文本等,以便您可以明確決定哪些部分受到影響。 您仍然使用上面的replaceAll() ,但僅將其應用於需要它的部分。

幾乎作為一項規則,您絕對不會使用正則表達式來處理XML,或解析包含嵌套或轉義引號的字符串,或解析CSV或TSV文件。 這些數據格式通常不適合使用正則表達式。

如果您確定XML文件中的元素值沒有任何連字符,或者如果它們受更改影響並不重要,那么您可以使用以下代碼:

碼:

String input="<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>";
//this regex will match all letters preceded by a hyphen
Matcher m = Pattern.compile("-[a-zA-Z]").matcher(input);
//use a string builder to manipulate the intermediate strings that are constructed
StringBuilder sb = new StringBuilder();
int last = 0;

//for each match
while (m.find()) {
    //append the substring between the last match (or the beginning of the string to the beginning of the current match 
    sb.append(input.substring(last, m.start()));
    //change the case to uppercase of the match
    sb.append(m.group(0).toUpperCase());
    //set last to the end of the current match
    last = m.end();
}
//add the rest of the input string          
sb.append(input.substring(last));
//remove all the hyphens and print the string
System.out.println(sb.toString().replaceAll("-", ""));

輸出:

<phoneResidence></phoneResidence><maritalStatus>1</maritalStatus><phoneOnRequest></phoneOnRequest>

改進:

如果您的XML元素的值中有連字符,並且您希望它們受到此更改的影響,那么您可以使用以下代碼(此簡化版僅在您的元素中沒有屬性時才起作用(您可以添加屬性的邏輯)並適用於小型XML樹(您可能必須增加更大的XML文檔的堆棧大小以避免stack overflow錯誤):

碼:

String input="<contact-root><phone-residence>abc-abc</phone-residence><marital-status>1</marital-status><phone-on-request><empty-node></empty-node></phone-on-request><empty-node/><not-really-empty-node>phone-on-request</not-really-empty-node></contact-root>";      
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(new StringReader(input)));          
StringBuilder strBuild = new StringBuilder();
xmlTrasversal(doc.getDocumentElement(),-1, strBuild);
System.out.println(input);
System.out.println();
System.out.println(strBuild.toString());

使用的功能:

  public static String capitalizeNext(String input){

        Matcher m = Pattern.compile("-[a-zA-Z]").matcher(input);
        StringBuilder sb = new StringBuilder();
        int last = 0;
        while (m.find()) {
            sb.append(input.substring(last, m.start()));
            sb.append(m.group(0).toUpperCase());
            last = m.end();
        }           
        sb.append(input.substring(last));
        return (sb.toString().replaceAll("-", ""));

  }

  public static void xmlTrasversal(Element e, int depth, StringBuilder strBuild)
  {
        ++depth;
        String spaces="  ";
        spaces=String.join("", Collections.nCopies(depth, spaces));
        if(!e.hasChildNodes())
            strBuild.append(spaces+"<"+capitalizeNext(e.getNodeName())+"/>"+System.getProperty("line.separator"));
        else if(e.getChildNodes().getLength()==1 && !(e.getChildNodes().item(0) instanceof Element))
        {
            strBuild.append(spaces+"<"+capitalizeNext(e.getNodeName())+">");
            strBuild.append(e.getTextContent());
        }
        else
        {
            strBuild.append(spaces+"<"+capitalizeNext(e.getNodeName())+">"+System.getProperty("line.separator"));
        }

        for (int i=0; i<e.getChildNodes().getLength();i++) 
        {
             if (e.getChildNodes().item(i) instanceof Element) {
                 xmlTrasversal((Element) e.getChildNodes().item(i), depth, strBuild);
            }
        }
        if(e.getChildNodes().getLength()==1 && !(e.getChildNodes().item(0) instanceof Element))
            strBuild.append("</"+capitalizeNext(e.getNodeName())+">"+System.getProperty("line.separator"));
        else if(e.hasChildNodes() && (e.getChildNodes().item(0) instanceof Element))
            strBuild.append(spaces+"</"+capitalizeNext(e.getNodeName())+">"+System.getProperty("line.separator"));

  }

輸入字符串的輸出:

<contactRoot>
  <phoneResidence>abc-abc</phoneResidence>
  <maritalStatus>1</maritalStatus>
  <phoneOnRequest>
    <emptyNode/>
  </phoneOnRequest>
  <emptyNode/>
  <notReallyEmptyNode>phone-on-request</notReallyEmptyNode>
</contactRoot>

嘗試這個:

    String str = "<phone-residence></phone-residence><marital-status>1</marital-status><phone-on-request></phone-on-request>";
    StringBuilder sb = new StringBuilder();
    StringTokenizer stk = new StringTokenizer(str,"-");
    while(stk.hasMoreTokens()){
        sb.append(WordUtils.capitalize(stk.nextToken()));
    }

    System.out.println(sb.toString());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM