Java 11 here, I'm trying to use regexes to build a method that accepts a String
, transforms it, and returns the transformed results.
Specifically, the string must only contain 1 alpha-numeric characters ([a-zA-Z0-9]
). Anytime two consecutive characters/elements either change case or switch from alpha -> numeric (and vice versa), I want to insert a hyphen ("-"
) between them.
Hence:
INPUT RESULT
====================================
flimFlam flim-Flam
fliMflam fliM-flam
fliM8fLam fli-M-8-f-Lam
flim$Flam Illegal! $ not allowed!
My best attempt so far:
public String hyphenate(String input) {
// validate
String regex = "[a-zA-Z0-9] ";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
if (!matcher.matches()) {
throw new IllegalArgumentException("Illegal!");
}
// TODO: how to efficiently iterate down the 'input' string and insert hyphen
// whenever case changes or 2 consecutive elements switch from alpha -> numeric
// or numeric -> alpha ?
}
Any ideas as to how to accomplish this hyphenation efficiently?
CodePudding user response:
Using regex lookarounds we can try:
String input = "fliM8fLam";
String output = input.replaceAll("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)|(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[a-z])", "-");
System.out.println(output); // fli-M-8-f-L-am
CodePudding user response:
- You can check for a non-alphanumeric character using
[^\\p{Alnum}]
. Learn more about patterns from the documentation. - You can get the matching groups using
[a-z] (?=[A-Z\d])|[A-Z] [a-z] |\d |[A-Z]
. Learn more about this pattern from this demo. You can concatenate the matching groups using a regular loop or the Stream API as shown in the following demo.
Demo:
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
class Main {
public static void main(String[] args) {
// Test
String[] arr = {
"flimFlam",
"fliMflam",
"fliM8fLam",
"flim$Flam"
};
for (String s : arr) {
try {
System.out.println("Trying to hyphenate " s);
System.out.println(hyphenate(s));
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
}
public static String hyphenate(String input) {
if (Pattern.compile("[^\\p{Alnum}]").matcher(input).find()) {
throw new IllegalArgumentException("Illegal!");
}
String regex = "[a-z] (?=[A-Z\\d])|[A-Z] [a-z] |\\d |[A-Z]";
return Pattern.compile(regex)
.matcher(input)
.results()
.map(MatchResult::group)
.collect(Collectors.joining("-"));
}
}
Output:
Trying to hyphenate flimFlam
flim-Flam
Trying to hyphenate fliMflam
fli-Mflam
Trying to hyphenate fliM8fLam
fli-M-8-f-Lam
Trying to hyphenate flim$Flam
Illegal!