mrida
mrida

Reputation: 1157

Uppercase all characters but not those in quoted strings

I have a String and I would like to uppercase everything that is not quoted.

Example:

My name is 'Angela'

Result:

MY NAME IS 'Angela'

Currently, I am matching every quoted string then looping and concatenating to get the result.

Is it possible to achieve this in one regex expression maybe using replace?

Upvotes: 2

Views: 1207

Answers (5)

Max F
Max F

Reputation: 71

I did not find my luck with these solutions, as they seemed to remove trailing non-quoted text. This code works for me, and treats both ' and " by remembering the last opening quotation mark type. Replace toLowerCase appropriately, of course...

Maybe this is extremely slow; I don't know:

private static String toLowercaseExceptInQuotes(String line) {
    StringBuffer sb = new StringBuffer(line);
    boolean nowInQuotes = false;
    char lastQuoteType = 0;
    for (int i = 0; i < sb.length(); ++i) {
        char cchar = sb.charAt(i);
        if (cchar == '"' || cchar == '\''){
            if (!nowInQuotes) {
                nowInQuotes = true;
                lastQuoteType = cchar;
            }
            else {
                if (lastQuoteType == cchar) {
                    nowInQuotes = false;
                }
            }

        }
        else if (!nowInQuotes) {
            sb.setCharAt(i, Character.toLowerCase(sb.charAt(i)));

        }
    }
    return sb.toString();
}

Upvotes: 0

Ajay Sant
Ajay Sant

Reputation: 705

Adding to the answer by @jan_kiran, we need to call the

appendTail()

method appendTail(). Updated code is:

List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("\\'(.*?)\\'");
String input = "'s'Hello This is 'Java' Not '.NET'";
Matcher regexMatcher = regex.matcher(input);

StringBuffer sb = new StringBuffer();
int counter = 0;
while (regexMatcher.find())
{// Finds Matching Pattern in String
    regexMatcher.appendReplacement(sb, "{"+counter+"}");
    matchList.add(regexMatcher.group());// Fetching Group from String
    counter++;
}

regexMatcher.appendTail(sb);

String formatted_string = MessageFormat.format(sb.toString().toUpperCase(), matchList.toArray());

Upvotes: 0

jan_kiran
jan_kiran

Reputation: 302

        List<String> matchList = new ArrayList<String>();
    Pattern regex = Pattern.compile("\\'(.*?)\\'");
    String input = "'s'Hello This is 'Java' Not '.NET'";
    Matcher regexMatcher = regex.matcher(input);

    StringBuffer sb = new StringBuffer();
    int counter = 0;
    while (regexMatcher.find())
    {// Finds Matching Pattern in String
        regexMatcher.appendReplacement(sb, "{"+counter+"}");
        matchList.add(regexMatcher.group());// Fetching Group from String
        counter++;
    }
    String format = MessageFormat.format(sb.toString().toUpperCase(), matchList.toArray());
    System.out.println(input);
    System.out.println("----------------------");
    System.out.println(format);

Input: 's'Hello This is 'Java' Not '.NET'

Output: 's'HELLO THIS IS 'Java' NOT '.NET'

Upvotes: 3

TheLostMind
TheLostMind

Reputation: 36304

Ok. This will do it for you.. Not efficient, but will work for all cases. I actually don't suggest this solution as it will be too slow.

public static void main(String[] args) {
        String s = "'Peter' said, My name is 'Angela' and I will not change my name to 'Pamela'.";
        Pattern p = Pattern.compile("('\\w+')");
        Matcher m = p.matcher(s);
        List<String> quotedStrings = new ArrayList<>();
        while(m.find()) {
            quotedStrings.add(m.group(1));
        }

        s=s.toUpperCase();
        // System.out.println(s);
        for (String str : quotedStrings)
        s= s.replaceAll("(?i)"+str, str);
        System.out.println(s);
    }

O/P :

'Peter' SAID, MY NAME IS 'Angela' AND I WILL NOT CHANGE MY NAME TO 'Pamela'.

Upvotes: 1

Jan
Jan

Reputation: 43169

You could use a regular expression like this:

([^'"]+)(['"]+[^'"]+['"]+)(.*)
# match and capture everything up to a single or double quote (but not including)
# match and capture a quoted string
# match and capture any rest which might or might not be there.

This will only work with one quoted string, obviously. See a working demo here.

Upvotes: 0

Related Questions