Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正在替换数量可变的项目。。。正则表达式?_Java_Regex - Fatal编程技术网

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没有考虑如何匹配一个或多个数字。