如何在任意位置拆分字符串(在Java中);字符,但从不在\“处;?正则表达式是否合适,如果合适,如何合适?
我需要在任意“字符”处拆分Java字符串。 最重要的是,前面的字符可能不是反斜杠(\) 因此,这些字符串将按如下方式拆分:如何在任意位置拆分字符串(在Java中);字符,但从不在\“处;?正则表达式是否合适,如果合适,如何合适?,java,regex,string,split,Java,Regex,String,Split,我需要在任意“字符”处拆分Java字符串。 最重要的是,前面的字符可能不是反斜杠(\) 因此,这些字符串将按如下方式拆分: asdnaoe"asduwd"adfdgb => asdnaoe, asduwd, adfgfb addfgmmnp"fd asd\"das"fsfk => addfgmmnp, fd asd\"das, fsfk 使用正则表达式有没有简单的方法来实现这一点? (我使用正则表达式是因为它对我来说是最简单的,编码人员。性能也不是问题
asdnaoe"asduwd"adfdgb => asdnaoe, asduwd, adfgfb
addfgmmnp"fd asd\"das"fsfk => addfgmmnp, fd asd\"das, fsfk
使用正则表达式有没有简单的方法来实现这一点?
(我使用正则表达式是因为它对我来说是最简单的,编码人员。性能也不是问题…)
先谢谢你
我是这样解决的:
private static String[] split(String s) {
char[] cs = s.toCharArray();
int n = 1;
for (int i = 0; i < cs.length; i++) {
if (cs[i] == '"') {
int sn = 0;
for (int j = i - 1; j >= 0; j--) {
if (cs[j] == '\\')
sn += 1;
else
break;
}
if (sn % 2 == 0)
n += 1;
}
}
String[] result = new String[n];
int lastBreakPos = 0;
int index = 0;
for (int i = 0; i < cs.length; i++) {
if (cs[i] == '"') {
int sn = 0;
for (int j = i - 1; j >= 0; j--) {
if (cs[j] == '\\')
sn += 1;
else
break;
}
if (sn % 2 == 0) {
char[] splitcs = new char[i - lastBreakPos];
System.arraycopy(cs, lastBreakPos, splitcs, 0, i - lastBreakPos);
lastBreakPos = i + 1;
result[index] = new StringBuilder().append(splitcs).toString();
index += 1;
}
}
}
char[] splitcs = new char[cs.length - (lastBreakPos + 1)];
System.arraycopy(cs, lastBreakPos, splitcs, 0, cs.length - (lastBreakPos + 1));
result[index] = new StringBuilder().append(splitcs).toString();
return result;
}
私有静态字符串[]拆分(字符串s){
char[]cs=s.toCharArray();
int n=1;
对于(int i=0;i=0;j--){
如果(cs[j]='\\')
sn+=1;
其他的
打破
}
如果(序号%2==0)
n+=1;
}
}
字符串[]结果=新字符串[n];
int lastbarkpos=0;
int指数=0;
对于(int i=0;i=0;j--){
如果(cs[j]='\\')
sn+=1;
其他的
打破
}
如果(序号%2==0){
char[]splitcs=新字符[i-lastbarkpos];
系统阵列复制(cs,lastBreakPos,splitcs,0,i-lastBreakPos);
lastBreakPos=i+1;
结果[索引]=新建StringBuilder().append(splitcs.toString();
指数+=1;
}
}
}
char[]splitcs=新字符[cs.length-(lastbarkpos+1)];
系统阵列复制(cs,lastbarkpos,splitcs,0,cs.length-(lastbarkpos+1));
结果[索引]=新建StringBuilder().append(splitcs.toString();
返回结果;
}
不管怎样,谢谢你所有的精彩回复!
(哦,尽管如此,我还是会使用@biziclop或@Alan Moore的版本,因为他们
“你比较短而且可能效率更高!=)当然,只要使用
(?<!\\)"
通常,您希望在剩余的
“
上拆分适当的解决方案,因为它不是真正的转义。仅供参考,下面是一个非regexp解决方案,它也处理\
的转义。(在现实生活中,这是可以简化的,没有必要使用START\u NEW
状态,但我试着用一种更容易阅读的方式编写它。)
公共类拆分器{
私有枚举状态{
在\u文本中,转义,开始\u新建;
}
公共静态列表拆分(字符串源){
LinkedList ret=新建LinkedList();
StringBuilder sb=新的StringBuilder();
State State=State.START\u NEW;
对于(int i=0;i
您可以用Java正则表达式解决这个问题;只是不要使用split()
核心正则表达式,
[^“\\]\\\.
,使用任何不是反斜杠或引号,或反斜杠后跟任何东西的东西,因此\\\”
将匹配为转义反斜杠(\
),后跟转义引号(\
).我在想反斜杠的某种消极的向后看?@LouisWasserman这和向前看不一样吗?:)“消极的回头看”是说你应该回头看而不是看到什么,不是说你在看一个负数的角色。@LouisWasserman我知道,这让我觉得这听起来有多可笑。我真的不明白这在所有情况下都不起作用。你在你声称失败的案例中测试过吗?这可以作为一个临时解决方案。谢谢!但是有没有什么简单的(?)方法来实现这一点,也许不使用RegEx呢?@TomS当然可以,通过编写自己的小状态机(你会有三个或四个状态)并逐字读取。这真的很简单..我在Regexplanet()中测试了你的表达式,它运行得很好。不是在lookback中。至少在Java中不是这样。
PS> 'addfgmmnp"fd asd\"das"fsfk' -split '(?<!\\)"'
addfgmmnp
fd asd\"das
fsfk
PS> 'addfgmmnp"fd asd\\"das"fsfk' -split '(?<!\\)"'
addfgmmnp
fd asd\\"das
fsfk
public class Splitter {
private enum State {
IN_TEXT, ESCAPING, START_NEW;
}
public static List<String> split( String source ) {
LinkedList<String> ret = new LinkedList<String>();
StringBuilder sb = new StringBuilder();
State state = State.START_NEW;
for( int i = 0; i < source.length(); i++ ) {
char next = source.charAt( i );
if( next == '\\' && state != State.ESCAPING ) {
state = State.ESCAPING;
} else if( next == '\\' && state == State.ESCAPING ) {
state = State.IN_TEXT;
} else if( next == '"' && state != State.ESCAPING ) {
ret.add( sb.toString() );
sb = new StringBuilder();
state = State.START_NEW;
} else {
state = State.IN_TEXT;
}
if( state != State.START_NEW ) {
sb.append( next );
}
}
ret.add( sb.toString() );
return ret;
}
}
public static void main(String[] args) throws Exception
{
String[] strs = {
"asdnaoe\"asduwd\"adfdgb",
"addfgmmnp\"fd asd\\\"das\"fsfk"
};
for (String str : strs)
{
System.out.printf("%n%-28s=> %s%n", str, splitIt(str));
}
}
public static List<String> splitIt(String s)
{
ArrayList<String> result = new ArrayList<String>();
Matcher m = Pattern.compile("([^\"\\\\]|\\\\.)+").matcher(s);
while (m.find())
{
result.add(m.group());
}
return result;
}