希望这是尝试解释我的目标的合理方式。
我的目标是从
更新字符串"unchanged DETECT_OPEN blah DETECT_CLOSE unchanged"
到
"unchanged UPDATED_OPEN blah UPDATED_CLOSE unchanged"
所以
DETECT_OPEN = [
DETECT_CLOSE = ]
UPDATED_OPEN = <
UPDATED_CLOSE = >
输入字符串上的
"this stays the same [i am wrapped] nothing to do here"
处理后
"this stays the same <i am wrapped> nothing to do here"
使用正则表达式解决这个问题有什么好方法吗? 我在java;所以java特定的例子是理想的;但任何正则表达式都是受欢迎的;我很乐意尝试从那里拿走它。
不确定它是否有任何区别;但是OPEN和CLOSE标记可以超过1个字符;并且长度不相等。
所以例如
DETECT_OPEN = ||
DETECT_CLOSE = |
简单示例:
"this stays the same ||i am wrapped| nothing to do here"
我无法使用多次查找替换的原因 - 适用于
等场景"this isn't an open || because it doesn't close. This open || is closed |, this close | was never opened"
因此处理后会是
"this isn't an open || because it doesn't close. This open < is closed >, this close | was never opened"
谢谢, 布伦特
答案 0 :(得分:0)
你绝对要使用正则表达式吗?如果没有,更简单的解决方案是:
"this stays the same [i am wrapped] nothing to do here".replace("[","<").replace("]",">");
对于一般化的解决方案:
String target = "this stays the same OPEN i am wrapped CLOSE nothing to do here";
String DETECT_OPEN = "OPEN";
String DETECT_CLOSE = "CLOSE";
String UPDATED_OPEN = "REPLACED OPEN";
String UPDATED_CLOSE = "REPLACED CLOSE";
String replaced = target.replace(DETECT_OPEN, UPDATED_OPEN).replace(DETECT_CLOSE, UPDATED_CLOSE);
修改:
这是为了回答您编辑过的问题。请注意,只要封闭分隔符不包含在开放分隔符中,此解决方案将适用于各种长度的分隔符。但是,它不会将打开的分隔符与封闭分隔符匹配。平衡括号问题比替换字符串要困难得多。可以找到代码示例here。
由于平衡括号问题,我不建议使用正则表达式。
答案 1 :(得分:0)
这是一个在Apache commons StringUtils的帮助下提供的解决方案。 (如果不可用,您可以自己实现countMatches。)
import org.apache.commons.lang.StringUtils;
public class Brackets {
final String DETECT_OPEN = "[";
final String DETECT_CLOSE = "]";
final String UPDATED_OPEN = "<";
final String UPDATED_CLOSE = ">";
public String matchingBrackets(String replaceMe) {
int openCount = StringUtils.countMatches(replaceMe, DETECT_OPEN);
int closeCount = StringUtils.countMatches(replaceMe, DETECT_CLOSE);
if (openCount != closeCount) {
// counts unequal, so return unchanged
return replaceMe;
}
String ans = replaceMe;
for (int i = 0; i < openCount; i++) {
int nextOpenIndex = StringUtils.indexOf(ans, DETECT_OPEN);
ans = StringUtils.replace(ans, DETECT_OPEN, UPDATED_OPEN);
int lastCloseIndex = StringUtils.lastIndexOf(ans, DETECT_CLOSE);
if (lastCloseIndex < nextOpenIndex) {
// have reversed open and close, as in )(
return replaceMe;
} else {
ans = StringUtils.replace(ans, DETECT_CLOSE, UPDATED_CLOSE);
}
}
return ans;
}
}
这是一个testNG测试。
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
public class BracketsTest {
@Test(dataProvider = "BracketsTest")
public void testMatchingBrackets(String expected, String processMe) throws Exception {
Brackets brackets = new Brackets();
assertEquals(expected, brackets.matchingBrackets(processMe));
}
@DataProvider
public Object[][] BracketsTest() {
return new Object[][]{
{"][", "]["},
{"<>", "[]"},
{"An unmatched brace [ [] means no change", "An unmatched brace [ [] means no change"},
{"this stays the same <i am wrapped> nothing to do here", "this stays the same [i am wrapped] nothing to do here"},
{"this stays the same ]i am wrapped[ nothing to do here", "this stays the same ]i am wrapped[ nothing to do here"},
{"the outer nested brackets < balance with these < inner >, and here's the outer > .", "the outer nested brackets [ balance with these [ inner ], and here's the outer ] ."},
{"The left is <balanced> and so is the <right>.", "The left is [balanced] and so is the [right]."}
};
}
}
请注意,案例的行为略有不同:
the outer nested brackets [ balance with these [ inner ], and here's the outer ] .
我认为这些是平衡的,而OP认为它不是,可能是因为连续两个开放括号。
答案 2 :(得分:0)
您可以使用捕获组执行此操作:
String replaced = input.replaceAll("\\[(.*?)\\]", "<$1>");
这会创建一个新字符串,[...]
替换为<...>
。
$1
是指模式中第一个匹配的(...)
内捕获的表达式。