需求是这样的,有些url有特殊字符,而这些特殊字符在windows的文件名里是不能拥有的,所以要把这样特殊字符都替换成别的字符
比如
3g.qq.com:80\forward.jsp
本地的文件名就是
3g.qq.com:80_forward.jsp也就说给我的参数是3g.qq.com:80\forward.jsp,而我要转为3g.qq.com:80_forward.jsp代码:String str = "3g.qq.com:80\forward.jsp";
System.out.println(str.replaceAll("\\", "_"));
报错Exception in thread "main" java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
\
^
at java.util.regex.Pattern.error(Pattern.java:1713)
at java.util.regex.Pattern.compile(Pattern.java:1466)
at java.util.regex.Pattern.<init>(Pattern.java:1133)
at java.util.regex.Pattern.compile(Pattern.java:823)
at java.lang.String.replaceAll(String.java:2190)
at com.lmiky.test.StringTest.main(StringTest.java:46)
我知道\f, \t等是转义符,我也知道正确的应该是\\,但是我现在能得到的就是\,不知道有什么办法实现
System.out.println(str);结果:3g.qq.com:80orward.jsp
String str = "3g.qq.com:80\\forward.jsp";
System.out.println(str);
System.out.println(str.replaceAll("\\\\", "_"));
String str="3g.qq.com:80\forward.jsp";
Pattern p = Pattern.compile("\\t");
Matcher m = p.matcher(str);
if (m.find()){
str = m.replaceAll("_\\t");
}
System.out.println(str);
}
String str = "3g.qq.com:80\\forward.jsp";
你在str下面打印一下str就知道是怎么回事了二,下面的str.replaceAll("\\\\", "_")对了,它首先进行java的转译,代表你要把正则表达式\\(也就是字符\) 换成 _ 之所以\在正则里需要用\\表示\是因为正则也需要转译。
System.out.println(str.replaceAll("\f", "_f").replaceAll("\\\\", "_"));
String str = "3g.qq.com:80\forward.jsp";
System.out.println(str.replace("\f", "_f"));
我很无语啊...
传给你的字符串,你看到的是3g.qq.com:80\forward.jsp
实际存储的是3g.qq.com:80\\forward.jsp懂?
这个3g.qq.com:80\forward.jsp是从数据库读取出来的,而我要转为3g.qq.com:80_forward.jsp,然后在本地找名字为3g.qq.com:80_forward.jsp的文件,然后读这个文件里的数据
只要你Syste.out.print出来看到是3g.qq.com:80\forward.jsp这样
他的实际存储就是 \\ 两个啊两个....
9楼之前谁知道是从数据库里去出来的?
那System.out.println(str.replaceAll("\\\\", "_"));就一点都没错。
你连上数据库去测试就完事了。
public static void main(String[] args) {
String url = "3g.qq.com:80\\tab\\back\\forward.jsp"; url = url.replaceAll("\\\\", "_"); System.out.println("Result:" + url);
}
}
如果实在绕不过弯来就干脆别用replaceAll改用replace就好了嘛:public class Test14 {
public static void main(String[] args) {
String url = "3g.qq.com:80\\tab\\back\\forward.jsp"; while (url.contains("\\"))
url = url.replace('\\', '_'); System.out.println("Result:" + url);
}
}
LZ 继续解释你的问题。哈哈。。
这个真的不是一个\或\\的问题,我想问的是一个\的话,要怎么替换
我来解释一下吧。\\ 前面2个在Java中表示一个“\”。
在使用正则表达式替换一个"\"的时候为什么要使用4个呢。
因为“\”在正则表达式中也是一个“特殊字符”同样是需要被转义的,所以在Java中输出2个“\\”在正则表达式中才能表示为一个“\”。
楼主可以查看一下JDK API DOC文档。我下面贴一点官方的说明。-------------------------------------------------------------------------------------
public final class Pattern extends Object implements Serializable正则表达式的编译表示形式。 指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。 因此,典型的调用顺序是 Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();在仅使用一次正则表达式时,可以方便地通过此类定义 matches 方法。此方法编译表达式并在单个调用中将输入序列与其匹配。语句 boolean b = Pattern.matches("a*b", "aaaaab");等效于上面的三个语句,尽管对于重复的匹配而言它效率不高,因为它不允许重用已编译的模式。
此类的实例是不可变的,可供多个并发线程安全使用。Matcher 类的实例用于此目的则不安全。 正则表达式的构造摘要
构造 匹配
字符
x 字符 x
\\ 反斜线字符 没有贴全,楼主还是自己去查询API吧。
假如字符串是:String str = "3g.qq.com:80\forward.jsp";
那么我们直接用System.out.println(str.replaceAll("\\\\", "_"));
是不行的.. 接着往下看:我们在前面的字符串加一个"\"
String str = "3g.qq.c\om:80\forward.jsp";
比如这样.
但是编辑器会报错,为什么呢,因为字符串中"\"是不能存在的,只能这样
String str = "3g.qq.c\\om:80\forward.jsp";
见证奇迹的时候到了:
什么这个能存在呢 String str = "3g.qq.com:80\forward.jsp";
因为系统没把这个字符中的"\" 当成"\",而是和"\f"同时存在的,所以系统不会报错.问题的根结找到了....
下面解决:根结这个根结:那么所有的字符串中的"\" 都不是作为"\"存在的
str = "\\test";再看下这个字符串的长度是多少然后再看下从数据库中读取出来的数据的长度是多少
然后再看下不从数据库中读取,而直接赋值的字符串的长度是多少或者把他们当成字符数据,一个一个的元素看他们的ascii码是多少
str.replaceAll("\\\\", "_")..OK 各位还有什么更好的办法,畅所欲言.. 互相学习
public static void main(String[] args) {
String input = "3g.qq.com:80\\forward.jsp"; Pattern p = Pattern.compile("\\\\");
Matcher m = p.matcher(input);
String r = m.replaceAll("_");
System.out.println(r); Pattern p2 = Pattern.compile("\\", Pattern.LITERAL);
Matcher m2 = p2.matcher(input);
String r2 = m2.replaceAll("_");
System.out.println(r2);
}
为了解决楼主的疑惑,我上面做了一个例子,楼主可以看一下。
第一个例子与第二个例子区别是在于第二个例子启动了LITERAL模式。API描述:LITERAL
public static final int LITERAL启用模式的字面值解析。
指定此标志后,指定模式的输入字符串就会作为字面值字符序列来对待。输入序列中的元字符或转义序列不具有任何特殊意义。 标志 CASE_INSENSITIVE 和 UNICODE_CASE 在与此标志一起使用时将对匹配产生影响。其他标志都变得多余了。 不存在可以启用字面值解析的嵌入式标志字符。
从以下版本开始:
1.5
另请参见:
常量字段值------------------------------------------------------------------------------
因为启动LITERAL模式之后,特殊字符将不具有特殊的意义,当作一个普通的文档对待。
所以第二个例子即使使用2个“\”也能够正确的替换。而默认LITERAL是不启动的,所以第一个例子还是使用4个"\"替换。
String str = "3g.qq.com:80\forward.jsp";
System.out.println(str.replaceAll("\\", "_"));String str = "3g.qq.com:80\\forward.jsp";
System.out.println(str.replaceAll("\\", "_"));
在补充一下,我认为楼主的认识是有误区的。
第一个例子显然不正确的,因为没有“\”所以无法替换。我打一个简单的比方:
页面上面有一个输入框用户输入了“\”他只是想要输入一个“\”,但是这个时候你难道要要求他输入2个“\”来表示1个“\”吗?
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
//String input = "3g.qq.com:80\\forward.jsp";
String input = s.next(); Pattern p = Pattern.compile("\\\\");
Matcher m = p.matcher(input);
String r = m.replaceAll("_");
System.out.println(r); Pattern p2 = Pattern.compile("\\", Pattern.LITERAL);
Matcher m2 = p2.matcher(input);
String r2 = m2.replaceAll("_");
System.out.println(r2);
}我把上面的例子修改了一个。
楼主这个时候可以通过控制台输入:3g.qq.com:80\forward.jsp。试一下,可以达到同样的效果。
这是因为当输入进去的时候是一个带有转义字符的字符串时,JDK内置会做转换工作,所以楼主在测试的时候就有误区。
你测试的时刻能不能写为String input = "3g.qq.com:80\forward.jsp",因为我实际的就是3g.qq.com:80\forward.jsp,还是说我哪里还有问题,帮忙指点指点
- -1,我不跟楼主争了,楼主还是自己去实验一下吧。
3g.qq.com:80\forward.jsp,假设你现在一个字符串,那么你打印出来如果是前面这个值的话,那你在测试的时候就写3g.qq.com:80\\forward.jsp,这没有问题,没有疑问。如果你的字符串就是3g.qq.com:80\forward.jsp,那么你在Java中打印的时候绝对不可能打印出“3g.qq.com:80\forward.jsp”这个效果,因为\f会被转义,所以你还是自己测试一下吧。无意义的争论还不如多测试一下。其实就是做一个简单的打印就完整了。
比刚才我说的数据字典 简单多了
不能在数据库插入时替换,因为别的地方也有用到这个数据,那些页面查出来的必须的url是真实的,也就是3g.qq.com:80\forward.jsp,而不是3g.qq.com:80\forward.jsp
不能,完毕。你写一个String input = "\f" 它打印出来不是\f,
但是如果你在数据库里 有一个\f ,它打印之后就是\f,
以上的话你能看明白不?所以,如果现在给你显示正确的值,这里的人能办到,但是你拿这段代码去套数据库出来的数据,它是错的,明白不?
select translate( 'ABC5\fD6D ', '\', '\\') x from dual;