如何从 JavaCC 令牌的图像中删除双引号?
How do you remove double quotes from the image of a JavaCC token?
在 JavaCC 中,我接受以下条件的字符串:
< STRING : "\"" ("\" ~[] | ~["\"","\"] )* "\"" >
因此图像最终会打印任何字符串但带有另一组双引号。
例如,我将输入:“这是一个句子。”
并且值将结果:“”这是一个句子。“”存储在一个字符串变量中。
在 Java 中有没有办法删除多余的双引号集,以便只打印:"This is a sentence."?
str = str.substring(1,str.length()-1)
Javacc 的替代品
Parsing Strings with JavaCC
如果您的令牌匹配的输入是 "Hello"
,那么令牌的 image
字段的值将是一个 7 个字符的字符串,其第一个和最后一个字符是双引号字符。它们并不是真正额外的,它们只是在输入中。说你写
void foo() : {
Token t ; }
{
t = <STRING>
{ System.out.println( t.image ) ; }
}
这将打印 7 个字符,然后是换行符。
现在,如果您不想要这些字符,那么@Bryan 的回答就可以了。
void foo() : {
Token t ; }
{
t = <STRING>
{ { String nakedImage = t.image.substring(1,t.image.length()-1) ;
System.out.println( nakedImage ) ; } }
}
请注意,没有删除引号。 String
Java 中的对象是不可变的,这意味着它们无法更改。真正发生的是创建了一个新的 String
对象并将对它的引用分配给 nakedImage
变量。 t.image
引用的 String
对象保持不变。
现在你还有处理反斜杠的问题。如果输入的是“Hello\tWorld”,那么t.image
的长度为14个字符,nakedImage
的长度为12个字符。我此时所做的是 运行 字符串通过函数构建一个新字符串,该字符串具有单个字符,其中 nakedImage
具有转义序列。因此,此示例中该函数的结果将是 11 个字符长。
void foo() : {
Token t ; }
{
t = <STRING>
{ { String nakedImage = t.image.substring(1,t.image.length()-1) ;
String unescapedImage = unescape( nakedImage ) ;
System.out.println( unescapedImage ) ; } }
}
这是一个这样的函数,基于我为 Java 编译器编写的函数。
private static String unescape( String str ) {
StringBuffer result = new StringBuffer() ;
for( int i=0, len = str.length() ; i<len ; ) {
char ch = str.charAt(i) ;
// Set ch and increment i ;
if( ch == '\' ) {
ch = str.charAt(i+1) ;
switch( ch ) {
case 'b' : ch = '\b' ; i += 2 ; break ;
case 't' : ch = '\t' ; i += 2 ; break ;
case 'n' : ch = '\n' ; i += 2 ; break ;
case 'f' : ch = '\f' ; i += 2 ; break ;
case 'r' : ch = '\r' ; i += 2 ; break ;
case '"' : case '\'' : case '\' : i+= 2 ; break ;
default:
/*TODO Deal with errors. */ } }
else {
i += 1 ; }
result.append( ch ) ; }
return result.toString() ;
}
在 JavaCC 中,我接受以下条件的字符串:
< STRING : "\"" ("\" ~[] | ~["\"","\"] )* "\"" >
因此图像最终会打印任何字符串但带有另一组双引号。
例如,我将输入:“这是一个句子。”
并且值将结果:“”这是一个句子。“”存储在一个字符串变量中。
在 Java 中有没有办法删除多余的双引号集,以便只打印:"This is a sentence."?
str = str.substring(1,str.length()-1)
Javacc 的替代品
Parsing Strings with JavaCC
如果您的令牌匹配的输入是 "Hello"
,那么令牌的 image
字段的值将是一个 7 个字符的字符串,其第一个和最后一个字符是双引号字符。它们并不是真正额外的,它们只是在输入中。说你写
void foo() : {
Token t ; }
{
t = <STRING>
{ System.out.println( t.image ) ; }
}
这将打印 7 个字符,然后是换行符。
现在,如果您不想要这些字符,那么@Bryan 的回答就可以了。
void foo() : {
Token t ; }
{
t = <STRING>
{ { String nakedImage = t.image.substring(1,t.image.length()-1) ;
System.out.println( nakedImage ) ; } }
}
请注意,没有删除引号。 String
Java 中的对象是不可变的,这意味着它们无法更改。真正发生的是创建了一个新的 String
对象并将对它的引用分配给 nakedImage
变量。 t.image
引用的 String
对象保持不变。
现在你还有处理反斜杠的问题。如果输入的是“Hello\tWorld”,那么t.image
的长度为14个字符,nakedImage
的长度为12个字符。我此时所做的是 运行 字符串通过函数构建一个新字符串,该字符串具有单个字符,其中 nakedImage
具有转义序列。因此,此示例中该函数的结果将是 11 个字符长。
void foo() : {
Token t ; }
{
t = <STRING>
{ { String nakedImage = t.image.substring(1,t.image.length()-1) ;
String unescapedImage = unescape( nakedImage ) ;
System.out.println( unescapedImage ) ; } }
}
这是一个这样的函数,基于我为 Java 编译器编写的函数。
private static String unescape( String str ) {
StringBuffer result = new StringBuffer() ;
for( int i=0, len = str.length() ; i<len ; ) {
char ch = str.charAt(i) ;
// Set ch and increment i ;
if( ch == '\' ) {
ch = str.charAt(i+1) ;
switch( ch ) {
case 'b' : ch = '\b' ; i += 2 ; break ;
case 't' : ch = '\t' ; i += 2 ; break ;
case 'n' : ch = '\n' ; i += 2 ; break ;
case 'f' : ch = '\f' ; i += 2 ; break ;
case 'r' : ch = '\r' ; i += 2 ; break ;
case '"' : case '\'' : case '\' : i+= 2 ; break ;
default:
/*TODO Deal with errors. */ } }
else {
i += 1 ; }
result.append( ch ) ; }
return result.toString() ;
}