次のクラスPlaceHolderConverter
を使用して、文字列を解析"my {} are beautiful"
して、変数が入力された文字列にします。
たとえばnew PlaceHolderConverter("\\{\\}").format("my {} are beautiful", "flowers")
、文字列を返します"my flowers are beautiful"
。
package something;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PlaceHolderConverter
{
public Pattern lookForVar;
public PlaceHolderConverter( String placeHolder )
{
this.lookForVar = Pattern.compile( placeHolder );
}
public String format( String text, String... args )
{
if ( args == null || args.length == 0 )
{
return text;
}
StringBuffer stringBuffer = new StringBuffer();
Matcher matcher = lookForVar.matcher( text );
short varCount = 0;
while ( matcher.find() )
{
matcher.appendReplacement( stringBuffer, args[varCount++] );
}
matcher.appendTail( stringBuffer );
return stringBuffer.toString();
}
}
次のテストでわかるように、ドルという特殊文字は Java 正規表現の特殊文字であるため、問題があります。私はそれを解決しようとしましPattern.quote()
たが、結果はありませんでした。
package something;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.regex.Pattern;
public class PlaceHolderConverterTest
{
private PlaceHolderConverter placeHolderConverter;
@Before
public void before()
{
placeHolderConverter = new PlaceHolderConverter( "\\{\\}" );
}
@Test // SUCCESS
public void whenStringArgsThenReplace()
{
String result = placeHolderConverter.format( "My {} are beautifull", "flowers" );
Assert.assertEquals( "My flowers are beautifull", result );
}
@Test // FAIL IllegalArgumentException illegal group reference while calling appendReplacement
public void assertEscapeDollar()
{
String result = placeHolderConverter.format( "My {} are beautiful", "flow$ers" );
Assert.assertEquals( "My flow$ers are beautiful", result );
}
@Test // FAIL IllegalArgumentException illegal group reference while calling appendReplacement
public void assertEscapeDollarWithQuote()
{
String result = placeHolderConverter.format( "My {} are beautiful", Pattern.quote("flow$ers") );
Assert.assertEquals( "My flow$ers are beautiful", result );
}
}
また、ドルを正規表現で使用する前に手動でエスケープしようとしましたが、arg2 に arg1 を含める必要があるのは嫌いなようです.replaceAll("\\$", "\\\\$")
。replaceAll
どうすれば修正できますか?
パッチはここで提供できますhttps://gist.github.com/3937872