【问题标题】:Splitting of string for `whitespace` & `and`拆分“空白”和“和”的字符串
【发布时间】:2014-03-27 05:14:20
【问题描述】:
String filter = phoneNumber eq '763436' and  carrier eq 'AT and T Mobility' and site startswith '256'

拆分应该给我以下信息:

字符串 1 = phoneNumber eq 763436

字符串 2 = 运营商 eq 'AT and T Mobility'

字符串 3 = 网站以 256 开头

更多的字符串 1 2 和 3 应该拆分成

字符串操作符 = phoneNumer 字符串操作符 = eq 字符串操作数 =763436

字符串操作符 = 运营商字符串操作符 = eq 字符串操作数 =AT 和 T Mobility

字符串操作符 = 站点字符串操作符 = 起始字符串操作数 =256

我可以分别对外部和内部使用 string.split("and") 和 split(" "),但我的字符串也包含空格和 and (例如 AT 和 T Mobility)。一个帮助是额外的和空格将出现在运算符中,仅在引号内。

任何帮助如何在java中拆分?

【问题讨论】:

  • 对不起,我的过滤器字符串如下所示:String filter ="phoneNumber eq 763436 and carrier eq 'AT and T Mobility' and site startswith 256" 只有 'AT and T Mobility' 会在引号内。

标签: java string split


【解决方案1】:

由于split 是基于正则表达式的,如果我没有正确阅读问题,您可以拆分为任一:

String[] split = yourString.split("(and)|\s+");

编辑

老实说,我建议您自己解析字符串以获得特定的东西,而不是通过正则表达式进行拆分:

public String[] parseRawString(String raw) {
    List<String> args = new ArrayList<>();
    StringBuilder sb = new StringBuilder();
    //whether or not to split on spaces
    boolean inQuotes = false;
    for (char c : raw.toCharArray()) {
        //if a quote is found
        if (c == '\'') {
            inQuotes = !inQuotes;
        //if a space is found outside quotes
        } else if (char == ' ' && !inQuotes) {
            args.add(sb.toString());
            sb.clear();
        //if a normal character is found or we're inside a quote
        } else if (char != ' ' || inQuotes) {
            sb.append(c);
        }
    }
    //add any last remnants that weren't added before the end
    if (!sb.isEmpty()) {
        args.add(sb.toString());
    }
    return args.toArray(new String[args.size()]);
}

这使得解析更容易:

String[] one = parseRawString("phoneNumber eq 763436");
/*
    one[0] = phoneNumber
    one[1] = eq
    one[2] = 763436
*/
String[] two = parseRawString("carrier eq 'AT and T Mobility'");
/*
    two[0] = carrier
    two[1] = eq
    two[2] = AT and T Mobility
*/
//etc...

我相信这似乎更接近你想要的。

【讨论】:

  • 答案只需要进行以下更改:删除与符号&amp; 并放置and 代替它,所以它看起来像这样:(and)|\s+
  • 更新中,谢谢@npinti 的关注
  • npinti 仍然没有帮助看到第一次拆分应该给我字符串 1 2 和 3,而不是每个字符串的进一步拆分应该给操作数运算符和值。抱歉,如果我的问题框架没有达到标准。
【解决方案2】:

既然你希望这些字符串作为键、操作数、值,你可以试试这个

    String regex="(?<key>\\S+)\\s+(?<operator>\\S+)\\s+(?<value>'[^']*'|\\S+)";
    for(String s:filter.split("\\s*and\\s*(?=([^']*'[^']*')*[^']*$)"))
    {
        Matcher m=Pattern.compile(regex).matcher(s);
        while(m.find())
        {
            System.out.println("Key:"+m.group("key"));
            System.out.println("operator:"+m.group("operator"));
            System.out.println("Value:"+m.group("value"));
        }
    }

【讨论】:

  • 你的帮助,但我需要以下方式首先拆分应该给我基于和类似的拆分字符串 1 = phoneNumber eq '763436' String 2 = carrier eq 'AT and T Mobility' String 3 = 站点以 256 开头,然后下一个拆分应将单个字符串拆分为运算符操作数和值。基本上我正在寻找 split 方法两次。
  • 我建议将 and\\s* 包围起来,这样您就不会在多余的空间上进行不必要的拆分,例如:split("(\\s*and\\s*|\\s+)(?=([^']*'[^']*')*$)")
  • 伙计们,我希望你们能解决我的顾虑,我不需要一口气全部拆分。我需要两次拆分方法,一次在水平上拆分,另一次拆分根据空格拆分结果字符串。看看我的例子。
  • @RohanK 一旦你像上面那样拆分成单独的标记,你可以继续从数组中一次取三个元素作为键、操作数、值
  • @Anirudh 谢谢兄弟....我同意,但我需要将该级别 1 字符串传递给服务,而不是服务将其再次拆分为三个不同的字符串.. 你提到的是正确的,但服务期望只有一个字符串形成我的身边。有什么帮助吗?
【解决方案3】:

查看此答案。 它正在工作

程序:

    String filter = "phoneNumber eq 763436 and  carrier eq 'AT and T Mobility' and site startswith 256";
    String[] split = filter.split("\\s*and\\s*(?=([^']*'[^']*')*[^']*$)");
    for (String s : split) {
       String[] split1 = s.trim().split(" ",3);
       for (String s1 : split1) {
            System.out.println(""+s1.replaceAll("'", ""));
        }
    }

输出:

    phoneNumber
    eq
    763436
    carrier
    eq
    AT and T Mobility
    site
    startswith
    256

查看更新后的程序,该程序适用于所有类型的输入字符串,如下所示,

1.String filter = "'phone Number' eq '763436' and carrier eq 'AT and T Mobility' and site 'startswith' '256'";

2.String filter = "'phone Number' eq '763436' and carrier eq 'AT and T Mobility' and site 'starts with' '256'";

3.String filter = "'phone and Number' eq '763436' and carrier eq 'AT and T Mobility' and site 'starts with' '256'";

4.String filter = "phoneNumber eq '763436' and carrier eq 'AT and T Mobility' and site startswith '256'";

5.String filter = "phoneNumber eq 763436 and carrier eq 'AT and T Mobility' and site startswith 256";

更多的字符串可以像上面一样使用单引号。它适用于所有字符串..

更新程序

    String filter = "'phone Number' eq 763436 and  carrier eq 'AT and T Mobility' and site 'startswith' '256'";
    String[] split = filter.split("\\s*and\\s*(?=([^']*'[^']*')*[^']*$)");
    for (String s : split) {
        String[] split1 = s.trim().split("\\s* \\s*(?=([^']*'[^']*')*[^']*$)");
        for (String s1 : split1) {
            System.out.println("" + s1.replaceAll("'", ""));
        }
    }

输出:

    phone Number
    eq
    763436
    carrier
    eq
    AT and T Mobility
    site
    startswith
    256

检查更新的代码并更新状态

【讨论】:

  • Prakash 如果过滤器是 phoneNumber eq 763436 和运营商 eq 'AT and T Mobility' 并且网站以 256 开头我从数字中删除了单引号
  • @RohanK 查看更新后的答案。它适用于我的答案中提到的许多字符串值。检查并更新
  • 谢谢。我检查了它的工作。但我喜欢 Anirudhh 的 Matcher 和 Regex 方式。但真的感谢您的努力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 2013-03-08
  • 1970-01-01
  • 2011-12-30
相关资源
最近更新 更多