Java 正在替换数量可变的项目。。。正则表达式?
好的。。。我对一个问题有一个不令人满意的解决办法 问题是我有这样的输入:Java 正在替换数量可变的项目。。。正则表达式?,java,regex,Java,Regex,好的。。。我对一个问题有一个不令人满意的解决办法 问题是我有这样的输入: {sup 19}F({sup 3}He,t){sup 19}Ne(p){sup 18}F ¹⁹F(³He,t)¹⁹Ne(p)¹⁸F 需要这样的输出: {sup 19}F({sup 3}He,t){sup 19}Ne(p){sup 18}F ¹⁹F(³He,t)¹⁹Ne(p)¹⁸F 我首先使用一系列替换将每个{sup xx}部分拆分为{sup x}{sup x},然后使用正则表达式匹配其中的每个部分,并用它们的U
{sup 19}F({sup 3}He,t){sup 19}Ne(p){sup 18}F
¹⁹F(³He,t)¹⁹Ne(p)¹⁸F
需要这样的输出:
{sup 19}F({sup 3}He,t){sup 19}Ne(p){sup 18}F
¹⁹F(³He,t)¹⁹Ne(p)¹⁸F
我首先使用一系列替换将每个{sup xx}部分拆分为{sup x}{sup x},然后使用正则表达式匹配其中的每个部分,并用它们的UTF-8单一等价物替换字符。“问题”是,{sup}部分可以有1、2或3位数字长(可能更多,我不知道),我想将它们“扩展”成单独的{sup}部分,每个部分有一位数字。(我对下标的{sub}也有同样的问题…)
我当前的解决方案如下(在java中):
我的问题是:无论有多少位数字(或至少是一些合理的数字),有没有一种方法可以在一次传递中做到这一点?是的,但这可能有点困难,你必须小心不要超过它 正则表达式:
(?:\{sup\s)?(\d)(?=\d*})}?
替换字符串:
{sup $1}
简短的解释:
(?: | start non-capturing group 1
\{ | match the character '{'
sup | match the substring: "sup"
\s | match any white space character
) | end non-capturing group 1
? | ...and repeat it once or not at all
( | start group 1
\d | match any character in the range 0..9
) | end group 1
(?= | start positive look ahead
\d | match any character in the range 0..9
* | ...and repeat it zero or more times
} | match the substring: "}"
) | stop negative look ahead
} | match the substring: "}"
? | ...and repeat it once or not at all
通俗地说:它只匹配一个数字,只有向前看时,中间有一个带有可选数字的}
。如果可能,子字符串{sup
和}
也会被替换
编辑:
更好的办法是:
(?:\{sup\s|\G)(\d)(?=\d*})}?
这样,字符串
“set={123}”
中的数字就不会被替换。我的第二个正则表达式中的\G
与前一个匹配结束的位置相匹配。是的,但这可能有点不对劲,您必须小心,它不会超过匹配
正则表达式:
(?:\{sup\s)?(\d)(?=\d*})}?
替换字符串:
{sup $1}
简短的解释:
(?: | start non-capturing group 1
\{ | match the character '{'
sup | match the substring: "sup"
\s | match any white space character
) | end non-capturing group 1
? | ...and repeat it once or not at all
( | start group 1
\d | match any character in the range 0..9
) | end group 1
(?= | start positive look ahead
\d | match any character in the range 0..9
* | ...and repeat it zero or more times
} | match the substring: "}"
) | stop negative look ahead
} | match the substring: "}"
? | ...and repeat it once or not at all
通俗地说:它只匹配一个数字,只有向前看时,中间有一个带有可选数字的}
。如果可能,子字符串{sup
和}
也会被替换
编辑:
更好的办法是:
(?:\{sup\s|\G)(\d)(?=\d*})}?
这样,字符串
“set={123}”
中的数字就不会被替换。第二个正则表达式中的\G
与前一个匹配结束的位置相匹配。当然,这是一个标准的正则表达式构造。您可以找到中的所有元字符,但出于您的目的,您可能需要“+”元字符或{1,3}贪婪量词。链接中的详细信息。当然,这是一个标准的正则表达式构造。您可以找到中的所有元字符,但出于您的目的,您可能需要“+”元字符或{1,3}贪婪量词。链接中的详细信息。执行此类操作的最简单方法是使用PHP的preg\u replace\u回调
或.NET的MatchEvaluator
委托。Java没有内置类似的东西,但它确实公开了让您自己实现它的低级API。这里有一种方法:
import java.util.regex.*;
public class Test
{
static String sepsup(String orig)
{
Pattern p = Pattern.compile("(\\{su[bp] )(\\d+)\\}");
Matcher m = p.matcher(orig);
StringBuffer sb = new StringBuffer();
while (m.find())
{
m.appendReplacement(sb, "");
for (char ch : m.group(2).toCharArray())
{
sb.append(m.group(1)).append(ch).append("}");
}
}
m.appendTail(sb);
return sb.toString();
}
public static void main (String[] args)
{
String s = "{sup 19}F({sup 3}He,t){sub 19}Ne(p){sup 18}F";
System.out.println(s);
System.out.println(sepsup(s));
}
}
结果:
{sup 19}F({sup 3}He,t){sub 19}Ne(p){sup 18}F
{sup 1}{sup 9}F({sup 3}He,t){sub 1}{sub 9}Ne(p){sup 1}{sup 8}F
如果需要,您可以继续生成上标和下标字符,然后插入它们。最简单的方法是使用PHP的
preg\u replace\u callback
或.NET的MatchEvaluator
委托。Java没有内置类似的东西,但它确实公开了让您自己实现它的低级API。这里有一种方法:
import java.util.regex.*;
public class Test
{
static String sepsup(String orig)
{
Pattern p = Pattern.compile("(\\{su[bp] )(\\d+)\\}");
Matcher m = p.matcher(orig);
StringBuffer sb = new StringBuffer();
while (m.find())
{
m.appendReplacement(sb, "");
for (char ch : m.group(2).toCharArray())
{
sb.append(m.group(1)).append(ch).append("}");
}
}
m.appendTail(sb);
return sb.toString();
}
public static void main (String[] args)
{
String s = "{sup 19}F({sup 3}He,t){sub 19}Ne(p){sup 18}F";
System.out.println(s);
System.out.println(sepsup(s));
}
}
结果:
{sup 19}F({sup 3}He,t){sub 19}Ne(p){sup 18}F
{sup 1}{sup 9}F({sup 3}He,t){sub 1}{sub 9}Ne(p){sup 1}{sup 8}F
如果您愿意,您可以继续生成上标和下标字符,然后插入它们。为什么将
{sup
部分标记为可选?它看起来将匹配“1}”。@Mike:OP希望将{sup 123}
替换为{sup 1}{sup 2}{sup 3}
。只有第一个数字前面有{sup
,最后一个数字后面有}
:这就是为什么它是可选的。@Mike:啊,我明白你的意思了。因此我说:“你必须小心,不要超过对手!”。请参阅我的第二个解决方案,其中包含\G
,这就是原因。第二个经过编辑的解决方案就是正确的解决方案。第一个错误地对其他输入进行替换,例如{sub 1}而不是{sup 1}。这些文档中有很多替换项。那么你很幸运:\G
在许多正则表达式实现中都没有实现(我只知道Java)。为什么你把{sup
部分标记为可选的?它看起来会匹配“1}”。@Mike:OP想用{sup 1}{sup 2}{sup 3}替换{sup 123}
。只有第一个数字前面有{sup
,最后一个数字后面有}
:这就是为什么它是可选的。@Mike:啊,我明白你的意思了。因此我说:“你必须小心,不要超过对手!”。请参阅我的第二个解决方案,其中包含\G
,这就是原因。第二个经过编辑的解决方案就是正确的解决方案。第一个错误地对其他输入进行替换,例如{sub 1}而不是{sup 1}。这些文档中有很多替换项。你很幸运:\G
在许多正则表达式实现中都没有实现(我只知道Java)。不,你误解了,OP没有考虑如何匹配一个或多个数字。不,你误解了,OP没有考虑如何匹配一个或多个数字。