Java 有没有办法分析传递给String.format(…)的模式

Java 有没有办法分析传递给String.format(…)的模式,java,string,format,formatter,Java,String,Format,Formatter,我想分析最终传递给客户的模式 String.format(String pattern, Object... args) 让我们考虑一下模式 "Integer is %d, String is %s" 有没有一种方法可以解析这个模式来确定 arg0将被格式化为数字 arg1将被格式化为字符串 显然,我可以用正则表达式来实现这一点,但是当在模式中指定索引等时,这会变得更加困难。例如,让我们考虑另一种模式 "String is %2$s, Integer is %1$d" 此处arg1在arg

我想分析最终传递给客户的模式

String.format(String pattern, Object... args)
让我们考虑一下模式

"Integer is %d, String is %s"
有没有一种方法可以解析这个模式来确定

  • arg0将被格式化为数字
  • arg1将被格式化为字符串
  • 显然,我可以用正则表达式来实现这一点,但是当在模式中指定索引等时,这会变得更加困难。例如,让我们考虑另一种模式

    "String is %2$s, Integer is %1$d"
    
    此处arg1在arg0之前指定,但这两个模式具有相同参数的相同格式化程序

    我真的很想使用核心java类来解析模式并对其进行分析,但似乎所有的方法都是私有的。在引擎盖下,
    String.format()
    使用一个


    最后,我尝试编写一个测试用例来验证我的各种语言翻译文件和冲突点(例如,一种语言为同一参数指定日期格式,另一种语言为同一参数指定数字格式)。

    对于开源项目,您可以基于。然后,在
    format
    ()方法的开关情况下,记住参数类型如下:

    代码:

    argument = args[argumentIndex];
    
    switch (conversion) {
        case 'b':
            argumentHashMap.put(new Integer(argumentIndex), Boolean.class);
            booleanFormat(argument, flags, width, precision, origConversion);
            break;
        case 's':
            argumentHashMap.put(new Integer(argumentIndex), String.class);              
            stringFormat(argument, flags, width, precision, origConversion);
            break;
        case 'd':
            argumentHashMap.put(new Integer(argumentIndex), Double.class);              
            decimalConversion(argument, flags, width, precision, origConversion);
            break;
        ...
    

    我添加了带有
    argumentHashMap

    的行,最后通过借用java源代码中的正则表达式解决了我的问题

    public class MyTest {
        static class PlaceHolder {
            int index;
            String flags;
            Integer width;
            Integer precision;
            String type;
            String conversion;
    
            @Override
            public String toString() {
                return String.format("PlaceHolder[index=%s, conversion=%s, flags=%s, width=%s, precision=%s, type=%s]",
                        index, conversion, flags, width, precision, type);
            }
        }
    
        public List<PlaceHolder> getPlaceholders(String pattern) {
            // %[argument_index$][flags][width][.precision][t]conversion
            Pattern regex = Pattern.compile("%((\\d+)\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.(\\d+))?([tT])?([a-zA-Z%])");
    
            int nextImplicitIndex = 1;
            Matcher matcher = regex.matcher(pattern);
    
            List<PlaceHolder> placeholders = new ArrayList<PlaceHolder>();
            while (matcher.find()) {
                String sIndex = matcher.group(2);
                int index = sIndex == null ? nextImplicitIndex++ : Integer.parseInt(sIndex);
                String flags = matcher.group(3);
                String sWidth = matcher.group(4);
                String sPrecision = matcher.group(6);
                String type = matcher.group(7);
                String conversion = matcher.group(8);
    
                PlaceHolder placeholder = new PlaceHolder();
                placeholder.index = index;
                placeholder.flags = flags;
                placeholder.width = sWidth == null ? null : new Integer(sWidth);
                placeholder.precision = sPrecision == null ? null : new Integer(sPrecision);
                placeholder.type = type;
                placeholder.conversion = conversion;
    
                placeholders.add(placeholder);
    
            }
            return placeholders;
        }
    
        @Test
        public void testGetPlaceholders() {
            System.out.println(getPlaceholders("Integer is %d, String is %s"));
            System.out.println(getPlaceholders("String is %2$s, Integer is %1$d"));
            System.out.println(getPlaceholders("%,6.2f"));
            System.out.println(getPlaceholders("Today is %tB %te, %tY %n"));
        }
    }
    
    [PlaceHolder[index=1, conversion=d, flags=, width=null, precision=null, type=null], PlaceHolder[index=2, conversion=s, flags=, width=null, precision=null, type=null]]
    [PlaceHolder[index=2, conversion=s, flags=, width=null, precision=null, type=null], PlaceHolder[index=1, conversion=d, flags=, width=null, precision=null, type=null]]
    [PlaceHolder[index=1, conversion=f, flags=,, width=6, precision=2, type=null]]
    [PlaceHolder[index=1, conversion=B, flags=, width=null, precision=null, type=t], PlaceHolder[index=2, conversion=e, flags=, width=null, precision=null, type=t], PlaceHolder[index=3, conversion=Y, flags=, width=null, precision=null, type=t], PlaceHolder[index=4, conversion=n, flags=, width=null, precision=null, type=null]]