如何在两个星号之间获取字符串?

时间:2015-05-13 16:38:09

标签: java

所以我看着reddit并且想知道他们是如何通过封装文本的星号来设置粗体和斜体的格式化的东西,所以我尝试在java中复制该效果。我尝试了很多东西,下面的代码是我试过的所有东西的混乱/混合/混搭

  public static ArrayList<String> redditReformat(String message) {
    ArrayList<String> single = new ArrayList<>();
    ArrayList<String> doubl = new ArrayList<>();
    ArrayList<String> fin = new ArrayList<>();

    if (message.contains("*") && !message.contains("**")) {
        ArrayList<Integer> asterisks = new ArrayList<>();

        for (int index = message.indexOf("*"); index >= 0; index = message.indexOf("*", index + 1)) {
            asterisks.add(index);
        }

        HashMap<Integer, Integer> patterns = new HashMap<>();
        for (int start : asterisks) {
            for (int end : asterisks) {
                if (start < end) {
                    if ((start + 1) != end) {
                        if (!patterns.containsKey(start) && !patterns.containsValue(end)) {
                            single.add(message.substring(start, end));
                            patterns.put(start, end);
                        }
                    } else {
                        if (message.charAt(start + 1) == message.charAt(start)) {
                            if (message.charAt(end + 1) == message.charAt(end)) {

                                ArrayList<Integer> doubleasterisks = new ArrayList<>();

                                if (!patterns.containsKey(start) && !patterns.containsValue(end)) {
                                    doubl.add(message.substring(start + 2, end - 1));
                                    if (doubleasterisks.size() < 2) {
                                        doubleasterisks.add(start + end);
                                    } else {
                                        patterns.put(doubleasterisks.get(1), doubleasterisks.get(2));
                                        doubleasterisks.clear();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    for (String s : single) {
        fin.add(s);
    }
    for (String d : doubl) {
        fin.add(d);
    }
    return fin;
}

是的它很乱,可能很可怕,我尝试过简单而复杂的事情,但这并不顺利。该方法应该在消息之间返回星号,所以就像&#34; haha​​ * lol * potato&#34; (stackoverflow格式化星号)

它目前返回&#34; * lol&#34;而不是&#34; * lol *&#34;当完成**

时它就不起作用了

当有多个封装时,它也会失败。

2 个答案:

答案 0 :(得分:2)

您可以使用正则表达式模式来查找事件:

String s = "blah *lol* blah";
Pattern pattern = Pattern.compile("\\*([^\\*]*)\\*");
Matcher matcher = pattern.matcher(s);
while (matcher.find()) {
    System.out.println(matcher.group(1));
}

打印:

lol

如果您以前没有遇到正则表达式,我强烈建议您了解它们。它们在许多文本提取/文本复制情况下都很有用。

表达式:

\\*([^\\*]*)\\*

细分如下:

\\*      match an asterisk (it's escaped with a backslash
         because * is a meaningful character in a regular 
         expression. It has to be double escaped because
         backslash is a meaningful character in a Java
         string.

(        start a capturing group

[^\\*]*  match zero or more characters that are not asterisk

)        end the capturing group

\\*      match another asterisk              

(实际上,正则表达式可能无法完美处理每个案例,因为它们不会处理嵌套,例如*italic **bold***,但可能已经足够好了。一个&#34;正确的解决方案会写一些lexing / parsing代码,一次接受每个字符,并保持状态。对于这种情况,你甚至可能需要回溯,因为它不清楚***是否开始斜体或粗体部分直到你进一步解析。)

如果您需要此功能,则预先写好Markdown解析器lots

答案 1 :(得分:1)

编辑:更新后使用Bukkit的ChatColor常量

正如评论中的人所说,你应该使用正则表达式完成这项任务。

阅读有关Minecraft聊天格式的信息,似乎为了使text加粗,你需要像这样围绕它:§ltext§r。对于下划线,它类似:§ntext§r。为了在Java代码中包含特殊字符,您可以使用unicode \u00a7

下面是一些使用正则表达式将单个星号替换为下划线并将双星号替换为粗体的示例代码:

public static String applyFormatting(String message) {
  // BOLD: replace all occurrences of "**text**" with BOLD+"text"+RESET
  message = message.replaceAll("\\*\\*([^\\*]*)\\*\\*", ChatColor.BOLD + "$1" + ChatColor.RESET);
  // UNDERLINE: replace all occurrences of "*text*" with ITALIC+"text"+RESET
  message = message.replaceAll("\\*([^\\*]*)\\*", ChatColor.ITALIC + "$1" + ChatColor.RESET);
  return message;
}

但这不适用于**This *is* a test**之类的嵌套格式 它尚未经过Minecraft测试。