0

在 Java 上,我知道接下来没问题:

String test="aaa";
System.out.println(String.format(test,"asd"));

(打印“aaa”)

但是,我希望能够处理相反的事情,例如:

String test="aaa%sbbb";
System.out.println(String.format(test));

(这会产生一个异常 java.util.MissingFormatArgumentException )

我希望使其尽可能通用,无论有多少说明符/参数,如果没有足够的值,只需忽略它们(从有问题的位置跳过所有说明符)并编写字符串的其余部分(例如,在我展示的情况下,它将写为 "aaabbb" ) 。

是否有可能开箱即用,还是我应该编写一个函数来做到这一点?

4

2 回答 2

1

好的,我想我有一个可行的解决方案,而且我还认为它支持 String.format 支持的所有内容:

public static String formatString(final String stringToFormat,final Object... args)
  {
  if(stringToFormat==null||stringToFormat.length()==0)
    return stringToFormat;
  int specifiersCount=0;
  final int argsCount=args==null ? 0 : args.length;
  final StringBuilder sb=new StringBuilder(stringToFormat.length());
  for(int i=0;i<stringToFormat.length();++i)
    {
    char c=stringToFormat.charAt(i);
    if(c!='%')
      sb.append(c);
    else
      {
      final char nextChar=stringToFormat.charAt(i+1);
      if(nextChar=='%'||nextChar=='n')
        {
        ++i;
        sb.append(c);
        sb.append(nextChar);
        continue;
        }
      // found a specifier
      ++specifiersCount;
      if(specifiersCount<=argsCount)
        sb.append(c);
      else while(true)
        {
        ++i;
        c=stringToFormat.charAt(i);
        // find the end of the converter, to ignore it all
        if(c=='t'||c=='T')
          {
          // time prefix and then a character, so skip it
          ++i;
          break;
          }
        if(c>='a'&&c<='z'||c>='A'&&c<='Z')
          break;
        }
      }
    }
  return String.format(sb.toString(),args);
  }

和一个测试,只是为了证明它有效:

System.out.println(formatString("aaa%sbbb"));
System.out.println(formatString("%da%sb%fc%tBd%-15se%16sf%10.2fg"));

可悲的是,它会在途中创建一个新的 stringBuilder 和一个字符串,但它可以工作。

于 2013-05-12T19:34:02.340 回答
0

是否有可能开箱即用,还是我应该编写一个函数来做到这一点?

开箱即用是不可能的。标准实现中没有任何内容可以忽略这一点。

我想您可以编写一个处理格式字符串的函数,以摆脱“不需要的”格式说明符。但很可能更容易:

  • 根据您拥有的参数数量选择或生成格式字符串,
  • format为每个参数调用一次方法,或者
  • 完全以其他方式进行格式化。
于 2013-05-11T23:43:01.803 回答