基于多个正则表达式规则插入字符串的算法

Algorithm to insert string based on multiple regex rules

我正在创建一个 Markdown 风格的标记界面。 例如,当用户输入 **example string** 时,使用正则表达式查找两次出现的 ** (定义粗体文本),实际明文将更改为 <b>**example string**</b> 并呈现为HTML。

这是我将用户输入解析为HTML:

的思路
  1. 对于正则表达式规则中的每个规则
  2. 每次出现 start pattern(当前正则表达式规则)
  3. start pattern 结束后 获取所有文本(称为 start substring
  4. end patternstart substring
  5. 中的第一个实例
  6. 从文本中提取substring(start_match.start() + end_match.end())
  7. 将其附加到最初为空白的 final text 字符串
  8. 通过 substring(start_match.start() + end_match.end()) 剔除剩余文本,将其反馈到 2 处读取的文本中。

我的代码:

public static String process(String input_text) {
    String final_text = "";
    String current_text = input_text;

    for (MarkdownRule rule : _rules) {
        Pattern s_ptrn = rule.getStartPattern();    // Start pattern
        Pattern e_ptrn = rule.getEndPattern();      // End pattern

        /* For each occurrence of the start pattern */
        Matcher s_matcher = s_ptrn.matcher(current_text);
        while (s_matcher.find()) {
            int s_end = s_matcher.end();
            int s_start = s_matcher.start();

            /* Take all text after the end of start match */
            String working_text = current_text.substring(s_end); // ERROR HERE

            /* For first instance of end pattern in remaining text */
            Matcher e_matcher = e_ptrn.matcher(working_text);
            if (e_matcher.find()) {

                /* Take full substring from current text */
                int e_end = e_matcher.end();
                working_text = current_text.substring(s_start, s_end + e_end);

                /* Append to final text */
                working_text = new StringBuilder(working_text).insert(0, "<b>").append("</b>").toString();
                final_text = new StringBuilder(final_text).append(working_text).toString();

                /* Remove working text from current text */
                current_text = new StringBuilder(current_text).substring(s_start + e_end);
            }
        }
    }

    return final_text;
}

虽然理论上这应该可以正常工作,但我在这一行得到了 StringIndexOutOfBoundsException

/* Take all text after the end of start match */
String working_text = current_text.substring(s_end);

当我使用输入文本时 **example**。我相信它在第一次出现 start pattern 时工作正常(在索引 0 和 1),但是随后字符串没有被正确剔除,然后在明文 ** 上调用循环,这给超出范围的错误。 (不过,我不能保证这一点——这正是我根据自己的测试所相信的)

不幸的是,我的故障排除无法修复错误。在此先感谢您的帮助。

你正在改变(缩小)current_text

/* Remove working text from current text */
current_text = new StringBuilder(current_text).substring(s_start + e_end);

虽然匹配器存储了初始 current_text 字符串,但无论您之后对 current_text 做什么,它都不会改变。

/* For each occurrence of the start pattern */
Matcher s_matcher = s_ptrn.matcher(current_text);

您需要为新字符串使用新的匹配器。