Merge pull request #8796 from ashleyfrieze/BAEL-3905-how-to-replace-tokens-in-strings

BAEL-3905 - replacing tokens tests and implementation
This commit is contained in:
Josh Cummings 2020-03-07 15:44:30 -07:00 committed by GitHub
commit f35e28d4dc
3 changed files with 148 additions and 0 deletions

View File

@ -25,6 +25,12 @@
<artifactId>jmh-generator-annprocess</artifactId> <artifactId>jmh-generator-annprocess</artifactId>
<version>${jmh-core.version}</version> <version>${jmh-core.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.15.0</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@ -0,0 +1,63 @@
package com.baeldung.replacetokens;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ReplacingTokens {
public static final Pattern TITLE_CASE_PATTERN = Pattern.compile("(?<=^|[^A-Za-z])([A-Z][a-z]*)(?=[^A-Za-z]|$)");
/**
* Iterate over the title case tokens in the input and replace them with lowercase
* @param original the original string
* @return a string with words replaced with their lowercase equivalents
*/
public static String replaceTitleCaseWithLowerCase(String original) {
int lastIndex = 0;
StringBuilder output = new StringBuilder();
Matcher matcher = TITLE_CASE_PATTERN.matcher(original);
while (matcher.find()) {
output.append(original, lastIndex, matcher.start())
.append(convert(matcher.group(1)));
lastIndex = matcher.end();
}
if (lastIndex < original.length()) {
output.append(original, lastIndex, original.length());
}
return output.toString();
}
/**
* Convert a token found into its desired lowercase
* @param token the token to convert
* @return the converted token
*/
private static String convert(String token) {
return token.toLowerCase();
}
/**
* Replace all the tokens in an input using the algorithm provided for each
* @param original original string
* @param tokenPattern the pattern to match with
* @param converter the conversion to apply
* @return the substituted string
*/
public static String replaceTokens(String original, Pattern tokenPattern,
Function<Matcher, String> converter) {
int lastIndex = 0;
StringBuilder output = new StringBuilder();
Matcher matcher = tokenPattern.matcher(original);
while (matcher.find()) {
output.append(original, lastIndex, matcher.start())
.append(converter.apply(matcher));
lastIndex = matcher.end();
}
if (lastIndex < original.length()) {
output.append(original, lastIndex, original.length());
}
return output.toString();
}
}

View File

@ -0,0 +1,79 @@
package com.baeldung.replacetokens;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.baeldung.replacetokens.ReplacingTokens.TITLE_CASE_PATTERN;
import static com.baeldung.replacetokens.ReplacingTokens.replaceTokens;
import static org.assertj.core.api.Assertions.assertThat;
public class ReplacingTokensUnitTest {
private static final String EXAMPLE_INPUT = "First 3 Capital Words! then 10 TLAs, I Found";
private static final String EXAMPLE_INPUT_PROCESSED = "first 3 capital words! then 10 TLAs, i found";
@Test
public void whenFindMatches_thenTitleWordsFound() {
Matcher matcher = TITLE_CASE_PATTERN.matcher(EXAMPLE_INPUT);
List<String> matches = new ArrayList<>();
while (matcher.find()) {
matches.add(matcher.group(1));
}
assertThat(matches)
.containsExactly("First", "Capital", "Words", "I", "Found");
}
@Test
public void exploreMatches() {
Matcher matcher = TITLE_CASE_PATTERN.matcher(EXAMPLE_INPUT);
while (matcher.find()) {
System.out.println("Match: " + matcher.group(0));
System.out.println("Start: " + matcher.start());
System.out.println("End: " + matcher.end());
}
}
@Test
public void whenReplaceTokensWithLowerCase() {
assertThat(ReplacingTokens.replaceTitleCaseWithLowerCase(EXAMPLE_INPUT))
.isEqualTo(EXAMPLE_INPUT_PROCESSED);
}
@Test
public void whenReplaceTokensWithLowerCaseUsingGeneralPurpose() {
assertThat(replaceTokens("First 3 Capital Words! then 10 TLAs, I Found",
TITLE_CASE_PATTERN,
match -> match.group(1).toLowerCase()))
.isEqualTo("first 3 capital words! then 10 TLAs, i found");
}
@Test
public void escapeRegexCharacters() {
Pattern regexCharacters = Pattern.compile("[<(\\[{\\\\^\\-=$!|\\]})?*+.>]");
assertThat(replaceTokens("A regex character like [",
regexCharacters,
match -> "\\" + match.group()))
.isEqualTo("A regex character like \\[");
}
@Test
public void replacePlaceholders() {
Pattern placeholderPattern = Pattern.compile("\\$\\{(?<placeholder>[A-Za-z0-9-_]+)}");
Map<String, String> placeholderValues = new HashMap<>();
placeholderValues.put("name", "Bill");
placeholderValues.put("company", "Baeldung");
assertThat(replaceTokens("Hi ${name} at ${company}",
placeholderPattern,
match -> placeholderValues.get(match.group("placeholder"))))
.isEqualTo("Hi Bill at Baeldung");
}
}