Java 将小数1到10替换为名称(“一”、“二”)

Java 将小数1到10替换为名称(“一”、“二”),java,regex,string,Java,Regex,String,我试图获取一个字符串,然后返回一个字符串,其中数字1到10被替换为这些数字的单词。例如: 我赢了10场比赛中的7场,得到了30美元 应成为: 我赢了十场比赛中的七场,得到了30美元 所以我这样做了: import org.apache.commons.lang3.StringUtils; String[] numbers = new String[] {"1", "2", "3","4","5","6","7","8","9","10"}; String[] words = new Str

我试图获取一个字符串,然后返回一个字符串,其中数字1到10被替换为这些数字的单词。例如:

我赢了10场比赛中的7场,得到了30美元

应成为:

我赢了十场比赛中的七场,得到了30美元

所以我这样做了:

import org.apache.commons.lang3.StringUtils;

String[] numbers = new String[] {"1", "2", "3","4","5","6","7","8","9","10"};
String[] words   = new String[]{"one", "two", "three","four","five","six",
    "seven","eight","nine","ten"};
System.out.print(StringUtils.replaceEach(phrase, numbers, words));
结果是:

我赢了10场比赛中的7场,得到了30美元

因此,我尝试了一种蛮力方法,我相信它可以通过正则表达式或更优雅的字符串操作得到改进:

public class StringReplace {

  public static void main(String[] args) {
    String phrase = "I won 7 of the 10 games and received 30 dollars.";
    String[] sentenceWords = phrase.split(" ");
    StringBuilder sb = new StringBuilder();
    for (String s: sentenceWords) { 
      if (isNumeric(s)) { 
        sb.append(switchOutText(s));
      }

      else { 
        sb.append(s);
      }
      sb.append(" ");

    }
    System.out.print(sb.toString());
  }

  public static String switchOutText(String s) { 
    if (s.equals("1"))
      return "one";
    else if (s.equals("2"))
      return "two";
    else if (s.equals("3"))
      return "three";
    else if (s.equals("4"))
      return "four";
    else if (s.equals("5"))
      return "fivee";
    else if (s.equals("6"))
      return "six";
    else if (s.equals("7"))
      return "seven";
    else if (s.equals("8"))
      return "eight";
    else if (s.equals("9"))
      return "nine";        
    else if (s.equals("10"))
      return "ten";
    else
      return s;        
  }

  public static boolean isNumeric(String s) { 
    try { 
      int i = Integer.parseInt(s);
    }
    catch(NumberFormatException nfe) { 
      return false;
    }
    return true;
  }

}

难道没有更好的办法吗?对正则表达式建议特别感兴趣

在用单词替换任何数字之前,您需要检查该数字后面或前面是否有其他数字。这可能是确保它不是更大数字的一部分的唯一方法。因此,您不会将“30”替换为“30”等等。这将允许它是“30”或“30.”或“30”或任何其他标点符号。因此,检查必须确保它不是0-9。

此方法使用正则表达式匹配由非数字(或开始或结束字符)包围的目标数字:

String[]words={“一”、“二”、“三”、“四”、“五”、“六”、“七”,
“八”、“九”、“十”};
字符串短语=“我赢了10场比赛中的7场,得到了30美元。”;

对于(int i=1;i),这似乎是对String.replaceAll()的一个非常简单的调用就足够了。请确保从10开始,以避免“one0”的问题。您可以尝试将
10
移动到数组的前面,以便在
1
之前对其进行求值。但可能还有更合适的更改。@KevinWorkman OP还需要处理避免将“30”中的“3”替换为“3”的问题@GriffeyDog很好。BobbyD17下面的答案似乎是一个很好的解决方案。我认为这在单个RegExp中是不可能的,因为据我所知,没有办法将映射表传递给RegExp。你还需要处理数字后面跟一个句点而不是空格的情况。好的一点。也许你必须先check确保每个短语后面没有数字。因此,在替换任何内容之前,请确保下一个字符不是数字。将其作为编辑添加。对于HTML,这可能会起作用,因为空格已折叠。在任何其他情况下,这是一个糟糕的解决方案。还需要检查前一个字符是否不是数字,否则为“31”将成为“3one”感谢您对此案例的更正。我做了更改。让我知道这是否是解决此问题的合理方法?它是否涵盖此案例:我最喜欢的数字是7,但我也喜欢5。@BobbyD17快速测试表明是的。是什么让您怀疑它可能不是?这是在我的答案下提出的评论之一。我只是想确保您检查一下我从来没有像你那样使用过这种模式,我也不太确定它是如何工作的。
String[] words = { "one", "two", "three", "four", "five", "six", "seven",
    "eight", "nine", "ten" };
String phrase = "I won 7 of the 10 games and received 30 dollars.";

for (int i = 1; i <= 10; i++) {
  String pattern = "(^|\\D)" + i + "(\\D|$)";
  phrase = phrase.replaceAll(pattern, "$1" + words[i - 1] + "$2");
}

System.out.println(phrase);