2

I have the following string "product-code" and I want to convert it to "productCode" using regular expression.

I think that te logic is very simple, I just need to replace the '-' char for the next converted to upper case.

But I don't know how to do that... can anybody help me?

Thanks a lot.

3
  • 1
    Not sure you can call a method in a regular expression. Commented Dec 31, 2010 at 14:33
  • @Peter you can in many languages, but not in Java. That would require methods to be first class citizens which probably won't happen before JDK8 Commented Dec 31, 2010 at 14:52
  • @Sean: The Java way would be to call a particular method on an object that implements an interface. However, calling a method from within a regular expression is a really bad idea as it binds you to how the RE engine does the matching rather than the more general notion of whether the RE matches. The correct thing is to use an RE to use REs within some other code that says what to do with each match. Commented Dec 31, 2010 at 15:32

5 Answers 5

4

Try using appendReplacement and appendTail -- they are very flexible and let you use arbitrary procedures for replacing fragments of strings.

package com.example.test;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CapitalizeDash {
    static public void main(String[] args)
    {
        test("ha----");
        test("onions");
        test("product-code");
        test("this-is-a-test");

    }

    // this matches a dash followed by any non-dash
    private static Pattern p = Pattern.compile("-([^-])");
    private static void test(String input) {
        System.out.println(capitalizeDash(input));
    }
    private static String capitalizeDash(String input) {
        StringBuffer sb = new StringBuffer();
        Matcher m = p.matcher(input);
        while (m.find())
        {
            m.appendReplacement(sb, m.group(1).toUpperCase());          
        }
        m.appendTail(sb);
        return sb.toString();       
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

This isn't as complicated as it seems. Using Pattern, Matcher and a few regular expression groups, it's just a few lines of code:

Pattern re = Pattern.compile("^([^-]+)-(.)(.*)$");
Matcher m = re.matcher("product-code");
if (m.matches())
{
    // Could do: s = m.group(1) + m.group(2).toUpperCase() + m.group(3)
    // Using a StringBuilder is more efficient, though.
    StringBuilder buf = new StringBuilder();
    buf.append(m.group(1));
    buf.append(m.group(2).toUpperCase());
    buf.append(m.group(3));
    System.out.println(buf.toString());
}

Turning this into a general function or method is left as an exercise to the reader. ;-)

EDIT

Handling multiple matches:

String s = "product-code boo-yah";
Pattern re = Pattern.compile("^([^-]+)-(.)(.*)$");
Matcher m = re.matcher(s);
while (m.matches())
{
    s = m.group(1) + m.group(2).toUpperCase() + m.group(3);
    m = re.matcher(s);
}

System.out.println(s);

NOTE: I did test that code.

1 Comment

Multiple matches can be handled by changing the pattern to remove the "^" and "$" anchors, and looping until Matcher.matches() returns false.
1

Regular expressions are for searching strings, not for replacing them. Just write simple java code like this:

public static String convert(String text) {
    StringBuilder resp = new StringBuilder(text.length());
    boolean upper = false;
    for (int i = 0; i < text.length(); i++) {
        char ch = text.charAt(i);
        if (ch == '-') {
            upper = true;
        } else {
            if (upper) {
              ch = Character.toUpperCase(ch);
              upper = false;
            }
            resp.append(ch);
        }
    }
    return resp.toString();
}

2 Comments

good example... note for future, code on SO is indented using 4 spaces, using the <code> won't do the job
Using regexps with groups results in less code than what's in this answer, however.
1

No need to over-complicate it...

  String p = "product-code";
  String[] values = p.split("-");
  char[] letters = values[1].toCharArray();
  letters[0] =Character.toUpperCase(letters[0]);
  System.out.println(values[0]+String.copyValueOf(letters));

Comments

0

Here is a variation loosely based on Jason S' solution (meaning that I started out with his code and then changed it to suit my needs). The clue is that Guava has a class that does exactly this conversion, the CaseFormat class (or enum, to be more precise). So what I did was search for lower case words with dashes and feed them to the CaseFormat converter. (Converting from LOWER_HYPHEN to LOWER_CAMEL)

public class CamelizeDashes {

    private static final Pattern WORD_WITH_DASHES =
        Pattern.compile("\\b(\\p{Lower}+(?:\\-\\p{Lower}+)+)\\b");

    private static String camelizeDashes(final String input) {
        final StringBuffer sb = new StringBuffer();
        final Matcher m = WORD_WITH_DASHES.matcher(input);
        while (m.find())
        {
            System.out.println("Match found: "+m.group());
            m.appendReplacement(sb, toCamelCase( m.group()));
        }
        m.appendTail(sb);
        return sb.toString();
    }
    public static void main(final String[] args)
    {
        test("Sed laoreet-neque-at libero luctus ultricies. Duis nulla justo, " +
            "tempor-nec viverra ut, convallis a diam. Praesent eget-nunc-sed " +
        "eros interdum sodales tempus-nec metus.");

    }
    private static void test(final String input) {
        System.out.println(camelizeDashes(input));
    }
    private static String toCamelCase(final String dashedword) {
        return CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_CAMEL, dashedword);
    }
}

Output:

Match found: laoreet-neque-at
Match found: tempor-nec
Match found: eget-nunc-sed
Match found: tempus-nec
Sed laoreetNequeAt libero luctus ultricies. Duis nulla justo, temporNec viverra ut, convallis a diam. Praesent egetNuncSed eros interdum sodales tempusNec metus.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.