使用正则表达式

时间:2016-10-13 14:59:50

标签: java regex string

我正在努力为以下数据准备正则表达式

我有这样的输入

"%,.2f","mm/DD/YYYY","1"

我希望得到像这样的结果

%,.2f
mm/DD/YYYY
1

我试过多个正则表达式但没有任何作用。

有没有办法在Java中获得这个?

我在内部框架中编写解析器,解析方法和参数,如formatCurrency("%,.2f","mm/DD/YYYY","1")。我写了一个正则表达式来分别获取函数名和参数。

使用逗号分割器有一些限制因为函数参数也可以包含逗号。我认为即使用引号分割也会有同样的问题。我认为唯一的方法是使用正则表达式进行解析,但理解正则表达式很难......

正则表达解析这将更有帮助

4 个答案:

答案 0 :(得分:1)

您希望使用逗号"作为分隔符在两个引号,之间拆分字符串。

如果您保留格式,此正则表达式会捕获所需的字符串:

"(.*?)"

Demo at Regex101

Java代码中的内容可能更适合您。不要忘记转义\"引号。它将被理解为String end / start否则:

List<String> results = new ArrayList<>();
Matcher m = Pattern.compile("\"(.*?)\"") .matcher(input);
while (m.find()) {
    results.add(m.group(1));
}

答案 1 :(得分:0)

您可以使用每列Matcherfind()

String s = "\"%,.2f\",\"mm/DD/YYYY\",\"1\"";
Matcher m = Pattern.compile("(?<=(?:^|,)\")([^\"]*)(?=\")").matcher(s);
List<String> cols = new ArrayList<>();
while (m.find()) {
    cols.add(m.group(1)); // group(0) works, too
}

System.out.println(cols);
// [%,.2f, mm/DD/YYYY, 1]

使周围的引号可选也有点容易,但有一个关于正则表达式是只写的原因的笑话。

关于正则表达式的一些解释:

由于Java字符串,所有引号都必须转义,因此您会在模式中看到[^\"]*之类的内容。

  

(?<=(?:^|,)\")

匹配文本

之前的逗号和引号
  

(?<=...)

非捕获正面观察。它允许您查看要尝试匹配的文本,即使这些字符已在先前模式中匹配。这也意味着group(0)不会包含逗号或引号,因此它更加万无一失。

  

(?:^|,)\"

匹配行的开头或逗号,跟着引号,但不捕获逗号(同样,group(0)可以工作,group(1)不是{{ 1}}“`。

  

"

匹配尽可能多的非引号字符并捕获它们。它们将位于([^\"]*)中,因为这是模式中的第一个捕获组。

  

group(1)

期待结束报价。这不会包含在(?=\")中,因为它是预先显示的。

答案 2 :(得分:0)

我认为尝试自己解析CSV文件不是一个好主意。该格式有很多极端情况,对于严肃的产品,我建议您使用现有的库。

我建议您使用Apache COMMONS CSV

只需在POM文件中添加依赖项:

<dependencies>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-csv</artifactId>
        <version>1.1</version>
    </dependency>
</dependencies>

代码很简单:

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.IOException;
import java.util.List;

/**
 */
public class CSVTester
{
    public static void main(String... args) throws IOException
    {
        String csvLine = "\"%,.2f\",\"mm/DD/YYYY\",\"1\"";

        List<CSVRecord> records = CSVParser.parse(csvLine, CSVFormat.DEFAULT).getRecords();

        records.stream().forEach(record -> {
            System.out.printf("%s\n%s\n%s",
                    record.get(0), record.get(1), record.get(2));
        });
    }
}

输出应符合预期:

%,.2f
mm/DD/YYYY
1

此外,只有在我的武器库中没有其他任何内容时,我才会去RegEx。

代码看起来不对,它们可以隐藏很多角落错误,它们是调试和修复的噩梦(几周后你会忘记你是如何制作RegEx的,你会花很多时间试图重新理解它。)

答案 3 :(得分:0)

您可以使用包含以下三种情况的以下内容:字符串开头,字符串中间,字符串结尾

(^"|","|"$)

<强> Demo

  • ^"将匹配字符串开头的
  • ","将与中间人匹配
  • "$将与最后的那些匹配

<强> IdeOne Demo

Result : [, %,.2f, mm/DD/YYYY", 1]