一个字符串可以包含一对多括号的小写字母,如String content = "This is (a) nightmare";
我想将字符串转换为"<centamp>This is </centamp>(a) <centamp>nightmare</centamp>";
所以基本上在这个字符串周围添加centamp标记但是如果它在括号中有一个小写字母应该从标记中排除。
这是我到目前为止所尝试过的,但它没有达到预期的效果。字符串中可能没有多对括号,并且每个括号都应该从标记中排除它。
Pattern pattern = Pattern.compile("^(.*)?(\\([a-z]*\\))?(.*)?$", Pattern.MULTILINE);
String content = "This is (a) nightmare";
System.out.println(content.matches("^(.*)?(\\([a-z]*\\))?(.*)?$"));
System.out.println(pattern.matcher(content).replaceAll("<centamp>$1$3</centamp>$2"));
答案 0 :(得分:2)
这可以在一个replaceAll
中完成:
String outputString =
inputString.replaceAll("(?s)\\G((?:\\([a-z]+\\))*+)((?:(?!\\([a-z]+\\)).)+)",
"$1<centamp>$2</centamp>");
它允许括号\\([a-z]+\\)
中的小写英文字母字符非空序列。
特点:
说明:
\G
断言匹配边界,即下一场比赛只能从最后一场比赛结束开始。它也可以匹配字符串的开头(当我们还没有找到任何匹配时)。
正则表达式的每个匹配将包含以下序列:0个或更多连续\\([a-z]+\\)
(允许之间没有空格),后跟至少1个不形成\\([a-z]+\\)
序列的字符
0或更多连续\\([a-z]+\\)
以涵盖字符串不以\\([a-z]+\\)
开头的情况,以及字符串不包含\\([a-z]+\\)
的情况。
在此部分的模式(?:\\([a-z]+\\))*+
中 - 请注意+
之后*
使量词占有,换句话说,它不允许回溯。简单地说,就是优化。
需要一个字符限制来防止添加包含空字符串的标记。
在此部分的模式中(?:(?!\\([a-z]+\\)).)+
- 请注意,对于每个字符,我会在匹配\\([a-z]+\\)
之前检查它是否是模式(?!\\([a-z]+\\)).
的一部分。
(?s)
标志会导致.
匹配任何字符,包括新行。这将允许标记包含跨越多行的文本。
答案 1 :(得分:1)
你只需用&lt; / centamp&gt; $ 1&lt; centamp&gt;替换所有“([a-z])”的出现。然后前置&lt; centamp&gt;并附加&lt; / centamp&gt;
String content = "Test (a) test (b) (c)";
Pattern pattern = Pattern.compile("(\\([a-z]\\))");
Matcher matcher = pattern.matcher(content);
String result = "<centamp>" + matcher.replaceAll("</centamp>$1<centamp>") + "</centamp>";
注意我在浏览器中写了以上内容,因此可能存在语法错误。
编辑以下是最简单的RegEx的完整示例。
import java.util.*;
import java.lang.*;
import java.util.regex.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
String content = "test (a) (b) and (c)";
String result = "<centamp>" +
content.replaceAll("(\\([a-z]\\))", "</centamp>$1<centamp>") +
"</centamp>";
result = result.replaceAll("<centamp></centamp>", "");
System.out.print(result);
}
}
答案 2 :(得分:0)
这是另一种使用清洁正则表达式的解决方案。解决方案更长,但它可以更灵活地调整条件以添加标签。
这里的想法是匹配包含小写字符的括号(我们不想标记的部分),然后使用匹配中的索引来标识我们要在标记中包含的部分。
// Regex for the parenthesis containing only lowercase English
// alphabet characters
static Pattern REGEX_IN_PARENTHESIS = Pattern.compile("\\([a-z]+\\)");
private static String addTag(String str) {
Matcher matcher = REGEX_IN_PARENTHESIS.matcher(str);
StringBuilder sb = new StringBuilder();
// Index that we have processed up to last append into StringBuilder
int lastAppend = 0;
while (matcher.find()) {
String bracket = matcher.group();
// The string from lastAppend to start of a match is the part
// we want to tag
// If you want to, you can easily add extra logic to process
// the string
if (lastAppend < matcher.start()) { // will not tag if empty string
sb.append("<centamp>")
.append(str, lastAppend, matcher.start())
.append("</centamp>");
}
// Append the parenthesis with lowercase English alphabet as it is
sb.append(bracket);
lastAppend = matcher.end();
}
// The string from lastAppend to end of string (no more match)
// is the part we want to tag
if (lastAppend < str.length()) {
sb.append("<centamp>")
.append(str, lastAppend, str.length())
.append("</centamp>");
}
return sb.toString();
}