我正在努力为以下数据准备正则表达式
我有这样的输入
"%,.2f","mm/DD/YYYY","1"
我希望得到像这样的结果
%,.2f
mm/DD/YYYY
1
我试过多个正则表达式但没有任何作用。
有没有办法在Java中获得这个?
我在内部框架中编写解析器,解析方法和参数,如formatCurrency("%,.2f","mm/DD/YYYY","1")
。我写了一个正则表达式来分别获取函数名和参数。
使用逗号分割器有一些限制因为函数参数也可以包含逗号。我认为即使用引号分割也会有同样的问题。我认为唯一的方法是使用正则表达式进行解析,但理解正则表达式很难......
正则表达解析这将更有帮助
答案 0 :(得分:1)
您希望使用逗号"
作为分隔符在两个引号,
之间拆分字符串。
如果您保留格式,此正则表达式会捕获所需的字符串:
"(.*?)"
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)
您可以使用每列Matcher
和find()
:
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]