2014-04-04 32 views
-3

我有几个类似的字符串。我想从中提取数字,添加数字并将其转换回相同的字符串格式。从字符串中提取数字,将它们添加并转换回字符串

而逻辑应该是通用的,即它应该适用于任何给定的字符串。

实施例:

字符串S1 = “1/9”;
String s2 =“12/4”;

上述两个字符串的提取应该是“13/13”(再次字符串)

我知道如何从任何给定的字符串中提取数字。我提到:How to extract numbers from a string and get an array of ints?

但我不知道如何把它们放回到相同的字符串格式。

任何人都可以帮助我吗?

注意:字符串格式可以是任何东西,我刚刚举了一个例子来解释。

+0

所以字符串格式就是数字可以是分数? –

+0

“1/9”,“12 \ 4”的输出应该是什么?或者它总是一样的'字符串格式'?如果不是,会发生什么? – amit

+1

在非数字('[^ 0-9]')的正则表达式上拆分每个字符串。将每个数组编号项目添加到下一个数组的项目中相同的索引处。然后加入最初的分隔符?你将能够做到这一点的唯一方法就是如果你有相同数量的分割对象。 – brandonscript

回答

0

谢谢@remus。阅读你的逻辑我能够构建下面的代码。此代码解决了具有相同格式的任何给定字符串的问题。

公共类测试{ 公共静态无效的主要(字串[] args){

ArrayList<Integer> numberList1 = new ArrayList<Integer>(); 
    ArrayList<Integer> numberList2 = new ArrayList<Integer>(); 
    ArrayList<Integer> outputList = new ArrayList<Integer>(); 

    String str1 = "abc 11:4 xyz 10:9"; 
    String str2 = "abc 9:2 xyz 100:11"; 

    String output = ""; 

    // Extracting numbers from the two similar string 
    Pattern p1 = Pattern.compile("-?\\d+"); 

    Matcher m = p1.matcher(str1); 
    while (m.find()) { 
     numberList1.add(Integer.valueOf(m.group())); 
    } 

    m = p1.matcher(str2); 
    while (m.find()) { 
     numberList2.add(Integer.valueOf(m.group())); 
    } 

    // Numbers extracted. Printing them 
    System.out.println("List1: " + numberList1); 
    System.out.println("List2: " + numberList2); 

    // Adding the respective indexed numbers from both the lists 
    for (int i = 0; i < numberList1.size(); i++) { 
     outputList.add(numberList1.get(i) + numberList2.get(i)); 
    } 

    // Printing the summed list 
    System.out.println("Output List: " + outputList); 

    // Splitting string to segregate numbers from text and getting the format 
    String[] template = str1.split("(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)"); 

    // building the string back using the summed list and format 
    int counter = 0; 
    for (String tmp : template) { 
     if (Test.isInteger(tmp)) { 
      output += outputList.get(counter); 
      counter++; 
     } else { 
      output += tmp; 
     } 
    } 

    // Printing the output 
    System.out.println(output); 
} 

public static boolean isInteger(String s) { 
    try { 
     Integer.parseInt(s); 
    } catch (NumberFormatException e) { 
     return false; 
    } 
    return true; 
} 

}

输出:

List1中:[11,4, 10,9]
列表2:[9,2,100,11]
输出列表:[20,6,110,20]
abc 20:6 xyz 110:20

1

看看这个:

public class StringTest { 

    public static void main(String[] args) { 
     String divider = "/"; 

     String s1 = "1/9"; 
     String s2 = "12/4"; 

     String[] fragments1 = s1.split(divider); 
     String[] fragments2 = s2.split(divider); 

     int first = Integer.parseInt(fragments1[0]); 
     first += Integer.parseInt(fragments2[0]); 

     int second = Integer.parseInt(fragments1[1]); 
     second += Integer.parseInt(fragments2[1]); 

     String output = first + divider + second; 
     System.out.println(output); 
    } 
} 

代码打印:

13/13

+0

'注意:字符串格式可以是任何东西,我只是举了一个例子来解释.'除了'“/”'以外的任何东西都失败了。 OP希望将其推广,因此您需要一个任意的分隔符 - 并且能够重现它。你的答案没有考虑到它。 – amit

+0

没错!除非你想让它在正则表达式上分开。 – brandonscript

+0

@amit:我更新了代码。现在'divider'可以设置为任何字符串 – Markus

1

使用正则表达式(和Markus'代码)

public class StringTest { 

    public static void main(String[] args) { 
     String s1 = "1/9"; 
     String s2 = "12&4"; 

     String[] fragments1 = s1.split("[^\\d]"); 

     String[] fragments2 = s2.split("[^\\d]"); 

     int first = Integer.parseInt(fragments1[0]); 
     first += Integer.parseInt(fragments2[0]); 

     int second = Integer.parseInt(fragments1[1]); 
     second += Integer.parseInt(fragments2[1]); 

     String output = first + divider + second; 
     System.out.println(output); 
    } 
} 

你应该可以从这里到达joining back from an array。如果你变得超级漂亮,你需要使用regular expression capture groups并将捕获的分隔符存储在某处。

+0

分频器未定义。你需要动态地找到它,缺少一个有效答案的步骤。 – amit

+0

这很重要,因为你想以相同的格式打印它们,如果它是'1/2 + 3',这种格式应该保留。硬编码'第一','第二'也应该是任意长度,我没有看到任何地方的答案中提到的长度应该是2. – amit

+0

我很熟悉它,这基本上是我指导你做的为了产生一个很好的答案,而不仅仅是一半。 – amit

0

该死的快速和肮脏不依赖于知道使用哪个分隔符。你必须确定,m1.group(2)和m2.group(2)是相等的(它代表分隔符)。

public static void main(String[] args) { 
    String s1 = "1/9"; 
    String s2 = "12/4"; 
    Matcher m1 = Pattern.compile("(\\d+)(.*)(\\d+)").matcher(s1); 
    Matcher m2 = Pattern.compile("(\\d+)(.*)(\\d+)").matcher(s2); 
    m1.matches(); m2.matches(); 
    int sum1 = parseInt(m1.group(1)) + parseInt(m2.group(1)); 
    int sum2 = parseInt(m2.group(3)) + parseInt(m2.group(3)); 
    System.out.printf("%s%s%s\n", sum1, m1.group(2), sum2); 
} 
+0

最佳答案国际海事组织,但它仍然缺乏事实,长度应该是动态的。根据我的理解,您还需要支持'1/2 \ 3',例如 – amit

+0

您是说,支持在一个字符串中出现两个以上的数字? – Harmlezz

+0

Yeap,在我看来,你需要支持它(问题的主体说与字符串,而不是2个数字 - 这个隐含的假设来自于这个例子,我们想回答这个问题,而不是例子) – amit

1

首先,拆你的字符串到比赛和非比赛:

public static class Token { 
    public final String text; 
    public final boolean isMatch; 

    public Token(String text, boolean isMatch) { 
     this.text = text; 
     this.isMatch = isMatch; 
    } 

    @Override 
    public String toString() { 
     return text + ":" + isMatch; 
    } 
    } 

    public static List<Token> tokenize(String src, Pattern pattern) { 
    List<Token> tokens = new ArrayList<>(); 
    Matcher matcher = pattern.matcher(src); 
    int last = 0; 
    while (matcher.find()) { 
     if (matcher.start() != last) { 
     tokens.add(new Token(src.substring(last, matcher.start()), false)); 
     } 
     tokens.add(new Token(src.substring(matcher.start(), matcher.end()), true)); 
     last = matcher.end(); 
    } 
    if (last < src.length()) { 
     tokens.add(new Token(src.substring(last), false)); 
    } 
    return tokens; 
    } 

一旦做到这一点,你可以创建你可以遍历和处理列表。

例如,这样的代码:

Pattern digits = Pattern.compile("\\d+"); 
System.out.println(tokenize("1/2", digits)); 

...输出:

[1:true, /:false, 2:true] 
+0

好多才多艺的答案。 +1。 – amit

0

考虑功能:

public String format(int first, int second, String separator){ 
    return first + separator + second; 
} 

然后:

System.out.println(format(6, 13, "/")); // prints "6/13" 
相关问题