【问题标题】:Splitting up input using regular expressions in Java在 Java 中使用正则表达式拆分输入
【发布时间】:2012-11-12 09:25:15
【问题描述】:

我正在制作一个程序,让用户输入化学物质,例如 C9H11N02。当他们输入时,我想把它分成几块,这样我就可以像 C9、H11、N、02 一样拥有它。当我拥有这样的它时,我想对其进行更改,以便将其设为 C10H12N203,然后放回原处一起。这是我到目前为止所做的。使用我使用过的正则表达式我可以提取整数值,但是我将如何获取 C10、H11 等?

System.out.println("Enter Data");

Scanner k = new Scanner( System.in );
String input = k.nextLine();

String reg = "\\s\\s\\s";
String [] data;

data = input.split( reg );

int m = Integer.parseInt( data[0] );
int n = Integer.parseInt( data[1] );

【问题讨论】:

  • @BheshGurung 不太确定...
  • 我不明白,你想用空格作为分隔符溢出什么字符串??
  • 您可以在 JavaScript 中通过调用正则表达式中的函数来执行此操作 - 请参阅 stackoverflow.com/questions/1742798/… - 但这是 Java...
  • @BheshGurung 看到了吗?你错了。使用正则表达式很容易完成

标签: java


【解决方案1】:

可以使用look arounds:

String[] parts = input.split("(?<=.)(?=[A-Z])");

环顾四周是零宽度、非消耗性断言。

这个正则表达式在两个环视匹配的地方分割输入:

  • (?&lt;=.) 表示“有 一个前面的字符”(即不在输入的开头)
  • (?=[A-Z]) 表示“下一个字符是大写字母”(所有元素都以A-Z 开头)

这是一个测试,包括一些边缘情况的双字符符号:

public static void main(String[] args) {
    String input = "C9KrBr2H11NO2";
    String[] parts = input.split("(?<=.)(?=[A-Z])");
    System.out.println(Arrays.toString(parts));
}

输出:

[C9, Kr, Br2, H11, N, O2]

如果您想拆分各个组件,请使用对 split() 的嵌套调用:

public static void main(String[] args) {
    String input = "C9KrBr2H11NO2";
    for (String component : input.split("(?<=.)(?=[A-Z])")) {
        // split on non-digit/digit boundary
        String[] symbolAndNumber = component.split("(?<!\\d)(?=\\d)");
        String element = symbolAndNumber[0];
        // elements without numbers won't be split
        String count = symbolAndNumber.length == 1 ? "1" : symbolAndNumber[1];
        System.out.println(element + " x " + count);
    }
}

输出:

C x 9
Kr x 1
Br x 2
H x 11
N x 1
O x 2

【讨论】:

  • 我删除了我的 cmets。 +1 证明我的评论是错误的。这是一个很好的解决方案。
  • 可能比我的解决方案更干净,但我很想看看在性能方面是否有任何差异......另外你可能想使用 Pattern 这样你就不必重新编译每次都使用正则表达式。
【解决方案2】:

您是否不小心在字母“O”(氧)应该在的某些公式中输入了零?如果是这样:

"C10H12N2O3".split("(?<=[0-9A-Za-z])(?=[A-Z])");

[C10, H12, N2, O3]

"CH2BrCl".split("(?<=[0-9A-Za-z])(?=[A-Z])");

[C, H2, Br, Cl]

【讨论】:

  • 对不起,我想我做到了。一旦像这样提取它,我是否可以进一步分解,以便将 C10 加 1 使其成为 C11?
  • lookBehind +1 - 但这不适用于两个字母化学符号的某些组合,例如CH2BrCl
  • @DNA:我认为现在应该修复它。
  • 不错。我认为您可以简化为 (?&lt;=.)(?=[A-Z])
  • @Joe24:在这种情况下,您可能希望使用 jrtc27 的答案。这个解决方案需要一个后续的正则表达式来从令牌中提取数字。
【解决方案3】:

我相信下面的代码应该允许您提取各种元素及其相关计数。当然,括号会让事情变得更复杂,但你没有问他们!

Pattern pattern = Pattern.compile("([A-Z][a-z]*)([0-9]*)");
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
    String element = matcher.group(1);
    int count = 1;
    if (matcher.groupCount > 1) {
        try {
            count = Integer.parseInt(matcher.group(2));
        } catch (NumberFormatException e) {
            // Regex means we should never get here!
        }
    }
    // Do stuff with this component
}

【讨论】:

  • 该模式会得到错误的 CH4 结果,例如 - 它应该返回 [C, H4] 但我认为它会返回 [CH4]。两个字母的化学符号总是大写小写。
猜你喜欢
  • 2021-12-04
  • 1970-01-01
  • 1970-01-01
  • 2019-10-14
  • 1970-01-01
  • 2013-07-28
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
相关资源
最近更新 更多