Last active
August 29, 2015 14:24
-
-
Save tarot/9e07fa851e648635990f to your computer and use it in GitHub Desktop.
JavaScript style String::replace for Apex (Salesforce)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class Strings { | |
| public interface Replacer { | |
| String apply(String match, String[] p, Integer offset, String str); | |
| } | |
| public static String replaceFirst(String str, String regExp, Replacer replacement) { | |
| return replaceFirst(str, Pattern.compile(regExp), replacement); | |
| } | |
| public static String replaceFirst(String str, Pattern p, Replacer replacement) { | |
| Matcher m = p.matcher(str); | |
| if (m.find()) { | |
| String sub = replacement.apply(m.group(), groupToList(m), m.start(), str); | |
| return str.substring(0, m.start()) + sub + str.substring(m.end()); | |
| } | |
| return str; | |
| } | |
| public static String replaceAll(String str, String regExp, Replacer replacement) { | |
| return replaceAll(str, Pattern.compile(regExp), replacement); | |
| } | |
| public static String replaceAll(String str, Pattern p, Replacer replacement) { | |
| String[] joiner = new String[] {}; | |
| Matcher m = p.matcher(str); | |
| Integer tail = 0; | |
| for (; m.find(); tail = m.end()) { | |
| joiner.add(str.substring(tail, m.start())); | |
| joiner.add(replacement.apply(m.group(), groupToList(m), m.start(), str)); | |
| } | |
| joiner.add(str.substring(tail)); | |
| return String.join(joiner, ''); | |
| } | |
| private static String[] groupToList(Matcher m) { | |
| String[] groups = new String[] {}; | |
| for (Integer i = 1, n = m.groupCount(); i <= n; ++i) { | |
| groups.add(m.group(i)); | |
| } | |
| return groups; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| @IsTest | |
| private class StringsTest { | |
| class ShouldNotCalledReplacer implements Strings.Replacer { | |
| public String apply(String match, String[] p, Integer offset, String str) { | |
| System.assert(false); | |
| return null; | |
| } | |
| } | |
| @IsTest | |
| static void testReplaceFirstNotMatched() { | |
| Strings.Replacer replacer = new ShouldNotCalledReplacer(); | |
| String actual = Strings.replaceFirst('abc', '[A-Z]', replacer); | |
| system.assertEquals('abc', actual); | |
| } | |
| @IsTest | |
| static void testReplaceAllNotMatched() { | |
| Strings.Replacer replacer = new ShouldNotCalledReplacer(); | |
| String actual = Strings.replaceAll('abc', '[A-Z]', replacer); | |
| system.assertEquals('abc', actual); | |
| } | |
| @IsTest | |
| static void testReplaceFirstWithGroup() { | |
| Strings.Replacer replacer = new TestReplaceFirstWithGroupReplacer(); | |
| String actual = Strings.replaceFirst('---ABCabc___XYZxyz---', '[A-Z]+([a-z]+)(\\d*)(_|-)', replacer); | |
| system.assertEquals('---(abc, , _)__XYZxyz---', actual); | |
| } | |
| class TestReplaceFirstWithGroupReplacer implements Strings.Replacer { | |
| public String apply(String match, String[] p, Integer offset, String str) { | |
| system.assertEquals('ABCabc_', match); | |
| system.assertEquals(new String[] { 'abc', '', '_' }, p); | |
| system.assertEquals(3, offset); | |
| system.assertEquals('---ABCabc___XYZxyz---', str); | |
| return '(' + String.join(p, ', ') + ')'; | |
| } | |
| } | |
| @IsTest | |
| static void testReplaceFirstWithoutGroup() { | |
| Strings.Replacer replacer = new TestReplaceFirstWithoutGroupReplacer(); | |
| String actual = Strings.replaceFirst('abc def', '[a-z]+', replacer); | |
| system.assertEquals('ABC def', actual); | |
| } | |
| class TestReplaceFirstWithoutGroupReplacer implements Strings.Replacer { | |
| public String apply(String match, String[] p, Integer offset, String str) { | |
| system.assertEquals('abc', match); | |
| system.assertEquals(new String[] {}, p); | |
| system.assertEquals(0, offset); | |
| system.assertEquals('abc def', str); | |
| return match.toUpperCase(); | |
| } | |
| } | |
| @IsTest | |
| static void testReplaceAllWithGroup() { | |
| Strings.Replacer replacer = new TestReplaceAllWithGroupReplacer(); | |
| String actual = Strings.replaceAll('---ABCabc___XYZxyz---', '[A-Z]+([a-z]+)(\\d*)(_|-)', replacer); | |
| system.assertEquals('---(abc, , _)__(xyz, , -)--', actual); | |
| } | |
| class TestReplaceAllWithGroupReplacer implements Strings.Replacer { | |
| Integer callCount = 0; | |
| public String apply(String match, String[] p, Integer offset, String str) { | |
| if (callCount == 0) { | |
| system.assertEquals('ABCabc_', match); | |
| system.assertEquals(new String[] { 'abc', '', '_' }, p); | |
| system.assertEquals(3, offset); | |
| system.assertEquals('---ABCabc___XYZxyz---', str); | |
| } else { | |
| system.assertEquals('XYZxyz-', match); | |
| system.assertEquals(new String[] { 'xyz', '', '-' }, p); | |
| system.assertEquals(12, offset); | |
| system.assertEquals('---ABCabc___XYZxyz---', str); | |
| } | |
| callCount++; | |
| return '(' + String.join(p, ', ') + ')'; | |
| } | |
| } | |
| @IsTest | |
| static void testReplaceAllWithoutGroup() { | |
| Strings.Replacer replacer = new TestReplaceAllWithoutGroupReplacer(); | |
| String actual = Strings.replaceAll('abc def', '[a-z]+', replacer); | |
| system.assertEquals('ABC DEF', actual); | |
| } | |
| class TestReplaceAllWithoutGroupReplacer implements Strings.Replacer { | |
| Integer callCount = 0; | |
| public String apply(String match, String[] p, Integer offset, String str) { | |
| if (callCount == 0) { | |
| system.assertEquals('abc', match); | |
| system.assertEquals(new String[] {}, p); | |
| system.assertEquals(0, offset); | |
| system.assertEquals('abc def', str); | |
| } else { | |
| system.assertEquals('def', match); | |
| system.assertEquals(new String[] {}, p); | |
| system.assertEquals(4, offset); | |
| system.assertEquals('abc def', str); | |
| } | |
| callCount++; | |
| return match.toUpperCase(); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment