3

背景

手工制作的成分表可能类似于:

180-200g/6-7oz flour
3-5g sugar
6g to 7g sugar
2 1/2 tbsp flour
3/4 cup flour

问题

这些项目必须标准化如下:

180 to 200 g / 6 to 7 oz flour
3 to 5 g sugar
6 g to 7 g sugar
2 1/2 tbsp flour
3/4 cup flour

代码

这是我到目前为止所拥有的:

text = text.replaceAll( "([0-9])-([0-9])", "$1 to $2" );
text = text.replaceAll( "([^0-9])/([0-9])", "$1 / $2" );
return text.replaceAll( "([0-9])([^0-9 /])", "$1 $2" );

问题

分割数据最有效的正则表达式是什么?

谢谢!

4

3 回答 3

2

您可以使用\b在单词边界处插入空格:

return text.replaceAll( "([0-9])-([0-9])",  "$1 to $2" )
           .replaceAll( "\\b", " ")
           .replaceAll( " {2,}", " ")
           .trim();
于 2012-06-06T07:01:06.900 回答
2

这是一个只使用环视插入空格的单行代码:

text = text.replaceAll("(?=-)|(?<=-)|(?<=[^\\d ])(?=/)|(?<=\\d/?)(?=[^\\d /])|(?<=\\D/)(?=\\d)", " ");

这适用于您的所有情况。这是一些测试代码:

public static void main(String[] args) {
    String[] inputs = { "180-200g/6-7oz flour", "3-5g sugar", "6g to 7g sugar", "2 1/2 tbsp flour", "3/4 cup flour" };
    String[] outputs = { "180 - 200 g / 6 - 7 oz flour", "3 - 5 g sugar", "6 g to 7 g sugar", "2 1/2 tbsp flour", "3/4 cup flour" };

    int i = 0;
    for (String input : inputs) {
        String output = input.replaceAll("(?=-)|(?<=-)|(?<=[^\\d ])(?=/)|(?<=\\d/?)(?=[^\\d /])|(?<=\\D/)(?=\\d)", " ");

        if (!output.equals(outputs[i++])) {
            System.out.println("Failed with input: " + input);
            System.out.println("Expected: " + outputs[i - 1]);
            System.out.println("  Actual: " + output);
        }
    }
}

正如预期的那样,输出什么也不是。

如果测试失败,这将帮助您了解哪里出了问题。

于 2012-06-06T14:28:23.650 回答
1

你可以结合

text = text.replaceAll( "([^0-9])/([0-9])", "$1 / $2" );
return text.replaceAll( "([0-9])([^0-9 /])", "$1 $2" );

通过使用类似的东西:

text.replaceAll("\\D(?=/\\d)|(?<=\\D)/(?=\\d)|\\d(?=[^0-9 /])", "$0 ");

我不知道这是否会更快。

如果经常使用这种方法,您可能会通过预编译所有模式并在此处使用已编译的模式来获得更多收益。

于 2012-06-06T13:35:37.313 回答