TransWikia.com

Replace character in string in specific position (ie not first, not all)

Salesforce Asked on January 1, 2021

I would like to replace one character in a string with an uppercase of the same character. Is there an elegant way to do this?
Eg I have ‘Donald Mcdonald’ and I would like to uppercase the first ‘d’ in ‘Mcdonald’ so I end up with ‘McDonald’

The string.replace function only gives the option to replace first or all. If I use the code below it obviously won’t work.

if(name.containsIgnoreCase(' mc')){
    integer mc = name.indexOfIgnoreCase(' mc') + 3;
    name = name.replaceFirst(name.mid(mc, 1), name.mid(mc,1).toUpperCase());
}

2 Answers

Thanks to @sfdcfox for the platform to build on. This is what I eventually ended up with which works perfectly for a string with multiple occurrences.

Pattern mcprefix = Pattern.compile('(?i)( ?ma?c)(\p{L}+|\P{L}+)');
list<string> names = name.split(' ');
list<string> fixednames = new list<string>();
for(string n : names){
    Matcher m2 = mcprefix.matcher(n);
    while(m2.find()) {
      String g1 = m2.group(1), g2 = m2.group(2);
      Integer start = n.indexOf(g1 + g2);
      if (start == 0 || n.substring(start - 1, start).isWhitespace())
        n = n.replaceFirst(g1 + g2, g1 + g2.capitalize());
    }
    fixednames.add(n);
}
name = String.join(fixednames, ' ');

Correct answer by Irene on January 1, 2021

Apex doesn't really support that. Strings are as in Java, immutable objects, so you can only create modified copies, but not update the original. It has to do with Java's String Pool. So, replaceFirst is probably appropriate in your case. Notably, the first parameter is actually a regular expression, so you can target exactly what you want to with some practice.

For example:

String name = 'old mcdonald';
String mc = '(?i)( mcd)';
name = name.replaceFirst(mc, ' McD');

You can also use String.split with similar effect, although this is probably the easiest way to get what you're looking for.

If you don't know what you're looking for, the following may also help:

Pattern mcprefix = Pattern.compile('(?i)( ma?c)(i|d|k)');
Matcher m = matcher.match(name);
while(m.find()) {
  String g1 = m.group(1), g2 = m.group(2);
  name = name.replaceFirst(mc, g1.capitalize()+g2.captialize());
}

Which should give you a pretty good algorithm to start from.

Answered by sfdcfox on January 1, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP