我正在解析一个包含数据的文本文件。
无论何时是文本数据,数据都在引号内。例如:“这里的任何文字”
问题是在数据中我也可以有引号,但它们后面总是会跟着另一个引号。例如:“文本,他说“你好”“”
我尝试了以下方法,但没有成功:
"(.+?)"(?!")
如何定义与该格式的文本数据匹配的正则表达式?
PS:不知道有没有帮助,但是每种类型的数据都用 ; 分隔
试试这个正则表达式(未测试):
"([^"]|"")*"
编辑:(没有意识到你不想匹配引号本身)
(?<=")([^"]|"")*(?=")
参考我在这里发表的上一篇文章,您应该可以使用以下内容:
(?:\"[^\"]*?\")*
这只会在双引号上拆分,但它也会为您提供引号之外的数据 - 希望这会有所帮助
public static void main(String[] args) {
// TODO code application logic here
Pattern p = Pattern.compile("[\"]{2}");
String[] result1 =
p.split("\"\"A01 A02\"\" \"\"B01 B02\"\"");
for (int i=0; i<result1.length; i++)
System.out.printf("DATA: ]]%s[[\n", result1[i]);
String[] result3 =
p.split("\"\"A21 \" A22\"\" STUFF \"\"B21 B22\"\"");
for (int i=0; i<result3.length; i++)
System.out.printf("DATA: ]]%s[[\n", result3[i]);
}
我可以确定,有一个字符,它不是消息的一部分,比如~
,你可以用 ~ 替换“”,进行匹配,最后转换~
回""
。
text.replaceAll ("\"\"", "~").
replaceAll ("(\"[^\"]+)", "($1)").
replaceAll ("~", "\"\"")
理论上。
实际上,我得到了开头和结尾匹配的引号,所以这个文本:
echo 'asdf " I say ""hello"" " foo " you say ""goodbye"" "baz'
被翻译成:
echo 'asdf (" I say ""hello"" )(" foo )(" you say ""goodbye"" )("baz' )
我找不到错误,但也许这个想法很有用。
如果您可以确定输入格式正确(没有不平衡的引号),那么这是有效的(如果格式不正确,那么您想做什么?):
"(([^"]*?)((""[^"]*?)*?))"(?!")
它是一个引号,后跟除引号以外的任何内容零次或多次,后跟任意数量的组,该组由一对双引号后跟任意数量的非引号组成,并以引号结尾而不是引号。
如果您确定每个数据都以 a 结尾,";
那么它会变得更容易一些
"(([^"]*?)((""[^"]*?)*?))";
但是该行的最后一个以引号结尾";
还是仅以引号结尾?
在 JoelFan 和 OldCurmudgeon 的启发下,这很有效,而且更简单一些:
"((?:[^"]|"")*)"
对于每种模式,数据都在捕获组 1 中。因此您的代码将类似于:
while (matcher.find()) {
data = matcher.group(1);
/* do whatever you want with the data such as replace '""' with '"' */
}
当然,在将它们编写为 Java 字符串时,您必须对模式中的引号进行转义,因此它们最终在您的代码中看起来像这样:
"\"(([^\"]*?)((\"\"[^\"]*?)*?))\"(?!\")"
或者
"\"(([^\"]*?)((\"\"[^\"]*?)*?))\";"
或(我将在我的代码中使用的)
"\"((?:[^\"]|\"\")*)\""