我正在创建一个 Markdown 风格的标记界面。
例如,当用户输入 **example string**
时, 正则表达式用于查找两次出现的 **
(定义粗体),实际的明文会变成<b>**example string**</b>
并呈现为 HTML。
这是我将用户输入解析为 HTML 的思路:
- 对于正则表达式规则中的每条规则
- 每次出现
start pattern
(当前正则表达式规则) - 在
start pattern
结束之后 获取所有文本(称之为start substring
) - 对于
end pattern
的第一个实例在start substring
- 接
substring(start_match.start() + end_match.end())
来自文字 - 将其附加到一个最初为空白的
final text
字符串 - 通过
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);
您需要为新字符串使用新的匹配器。
关于java - 基于多个正则表达式规则插入字符串的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41853115/