Reputation: 329
I want to turn a string into a html tag with a specified pattern like this:
Walking in the !boldstreet
I want to detect the !bold
in the string and turn the following word into "<b>street</b>
".
String s = "Walking in the !boldstreet"
String result = null;
String[] styles = {"!bold", "!italic", "!deleted", "!marked"};
String[] tags = {"b", "i", "del", "mark"};
List<String> indexer = new ArrayList<String>(Arrays.asList(tags));
int index = 0;
for (String x: styles) {
if (s.startsWith(x)) {
result = style(s, indexer.get(index));
break;
}
index++;
}
if (result == null) result = s; //there was no formatting
return result;
//style method
public String style(String text, String tag) {
return "<" + tag + ">" + text + "</" + tag + ">";
}
This works but when i pass something like this to it: "Walking !deletedin the !boldstreet"
only it will turn !boldstreet into html tags. How can i make it turn everything like those into html tags?
Upvotes: 1
Views: 122
Reputation: 140309
Try a pattern like:
Pattern pattern = Pattern.compile("!(bold|italic|deleted|marked)(.*?)\\b");
And then do the replacement something like:
Matcher matcher = pattern.matcher(s);
StringBuffer sb = new StringBuffer();
while (matcher.find()) {
String tag = getTagFor(matcher.group(1)); // Implement lookup of tag from the bit immediately after the !
String text = matcher.group(2);
sb.appendReplacement(sb, String.format("<%s>%s</%s>", tag, text, tag));
}
matcher.appendTail(sb);
String result = sb.toString();
getTagFor
might be something like:
String getTagFor(String code) {
switch (code) {
case "bold": return "b";
case "italic": return "i";
case "deleted": return "del";
case "marked": return "mark";
default: throw new IllegalArgumentException(code);
}
}
or it could simply be a pre-built map. (A map might be better, because you can build the pattern by joining its keys, so you don't have the problem of keeping pattern and lookup in sync).
Upvotes: 2
Reputation: 1579
Not as fancy as using a regex, but gets the job done:
HashMap<String, String> tagsAndStyles = new HashMap<>();
tagsAndStyles.put("!deleted", "del");
tagsAndStyles.put("!bold", "b");
tagsAndStyles.put("!italic", "i");
tagsAndStyles.put("!marked", "mark");
String input = "Walking !deletedin the !boldstreet";
StringBuilder builder = new StringBuilder();
for (String segment : input.split(" ")) {
for (String style : tagsAndStyles.keySet())
if (segment.contains(style)) {
String tag = tagsAndStyles.get(style);
segment = "<" + tag + ">" + segment.substring(style.length()) + "</" + tag + ">";
break;
}
builder.append(segment + " ");
}
builder.toString().trim();
Upvotes: 1
Reputation: 270850
Assuming that each !xxx
applies only to the word after it, and "words" are space separated...
static String[] styles = {"!bold", "!italic", "!deleted", "!marked"};
static String[] tags = {"b", "i", "del", "mark"};
// this method styles *one* word only
public static String styleWord(String word) {
for (int i = 0 ; i < styles.length ; i++) {
if (word.startsWith(styles[i])) {
String rest = word.substring(styles[i].length());
String cleaned = styleWord(rest); // handles nested tags!
return style(cleaned, tags[i]);
}
}
return word; // no styles
}
public static String style(String text, String tag) {
return "<" + tag + ">" + text + "</" + tag + ">";
}
// ...
String s = "Walking !deletedin the !boldstreet";
// splits the string into words
String[] words = s.split(" ");
// styles each word, and joins them all together again.
return Arrays.stream(words).map(EnclosingClass::styleWord).collect(Collectors.joining(" "));
Upvotes: 1