Java:正则表达式转义正则表达式

时间:2013-02-04 03:45:04

标签: java regex

此示例数据由Web Service返回

  

200,6,“美国加利福尼亚州”

我想使用split(",")拆分它们,并尝试使用简单的代码查看结果。

String loc = "200,6,\"California, USA\"";       
String[] s = loc.split(",");

for(String f : s)
   System.out.println(f);

不幸的是这是结果

200
6
"California
 USA"

预期结果应为

200
6
"California, USA"

我尝试了不同的正则表达式而没有运气。是否可以转义""内的给定正则表达式?

更新1 :添加了C#代码

更新2 :删除了C#代码

4 个答案:

答案 0 :(得分:3)

,(?=(?:[^"]|"[^"]*")*$)

这是你想要的正则表达式 (要将它放在split函数中,你需要转义字符串中的引号)

解释

你需要找到所有',而不是引号.. 那就是你需要预测(http://www.regular-expressions.info/lookaround.html)以查看当前匹配的逗号是在引号内还是在引号内。

为此,我们使用lookahead来基本确保当前匹配','后面跟着偶数个'''字符(意思是它位于引号之外)

所以 (?:[^"]|"[^"]*")*$表示仅在非引号字符结束时匹配或者在它们之间有任何引号的引号

(?=(?:[^"]|"[^"]*")*$)会预见上述匹配

,(?=(?:[^"]|"[^"]*")*$)最后这将与所有','匹配上述前瞻

答案 1 :(得分:2)

更简单的解决方案可能是使用现有库(例如OpenCSV)来解析数据。这可以使用这个库在两行中完成:

CSVParser parser = new CSVParser();
String [] data = parser.parseLine(inputLine);

如果您将来会有更复杂的CSV值(多行值,或元素中带有转义引号的值等),这将变得尤为重要。如果您不想添加依赖项,您可以始终使用其代码作为参考(尽管它不基于RegEx)

答案 2 :(得分:0)

如果有一个很好的Java词法分析器/解析器库,你可以定义一个类似于以下伪词法分析器的词法分析器:

Delimiter: ,
Item: ([^,"]+) | ("[^,"]+")
Data: Item Delimiter Data | Item 

词法分析器的工作原理是它从顶级令牌定义(在本例中为Data)开始,并尝试从字符串中形成令牌,直到它不能或直到字符串全部消失为止。因此,对于您的字符串,将发生以下情况:

  • 我想从200,6,“加利福尼亚,美国”制作数据。
  • 我可以从一个项目,一个分隔符和数据中创建数据。
  • 我看了 - 200是一个项目,然后,是一个分隔符,所以我可以将其标记并继续前进。
  • 我想用6,“加利福尼亚,美国”
  • 制作数据
  • 我可以从一个项目,一个分隔符和数据中创建数据。
  • 我看了 - 6是一个项目然后,是一个分隔符,所以我可以将其标记并继续前进。
  • 我想用“加利福尼亚,美国”制作数据
  • 我可以从一个项目,一个分隔符和数据中创建数据。
  • 我看了 - “加利福尼亚,美国”是一个项目,但我看不到它之后的分隔符,所以让我们试试别的。
  • 我可以从一个项目中创建数据。
  • 我看了 - “加利福尼亚,美国”是一个项目,所以我可以将其标记并继续前进。
  • 字符串为空。我受够了。这是你的代币。

(我了解了词法分析器如何从指南到PLY,Python词法分析器/解析器:http://www.dabeaz.com/ply/ply.html

答案 3 :(得分:0)

您好试试这个表达式。

public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String loc = "200,6,\"Paris, France\"";  
        String[] str1 =loc.split(",(?=(?:[^\"]|\"[^\"]*\")*$)");

        for(String tmp : str1 ){
            System.out.println(tmp);
        }

    }

}