我正在用Java编写程序,并且使用正则表达式遇到了一个小问题。我想要捕获未用引号括起来的所有内容。我有一个正则表达式,right here,但问题是,它不能在Java中使用。它使用(*SKIP)(*F)
技巧跳过".*"
,并找到其他任何内容(使用[^\W]
),但正如我所说,它不能在Java中使用。我有另一种模式,但不是我需要的,right here。它会在它前面或后面找到没有引号的所有内容。这个问题是,如果我有这样的话:Test1 "Hello World!" Test2
,并且会抓住Test1
,Test2
和World
。我不想获得World
,因为它在引号中。我想知道的是,是否有可能做我想做的事情,如果是这样的话。
答案 0 :(得分:1)
您必须匹配您想要避免的内容并使用捕获组来提取您想要的内容(我不认为还有其他方式)。一个方便的模式可以是:
(?:[^\w"]+|"[^"]*")*+(\w+)
为每个匹配返回捕获组1中的结果。 demo
注意:如果您想使用模式进行替换,请将第一部分放在捕获组中,并使用对该组的引用来启动替换字符串:
((?:[^\w"]+|"[^"]*")*+)(\w+)
其他方式,将您的字符串拆分为:(?:[^\w"]+|"[^"]*")+
您可以将"[^"]*"
更改为"[^"\\]*+(?s:\\.[^"\\]*)*+"?
以处理引用部分内的转义引号以及最终丢失的结束引用。
答案 1 :(得分:1)
不幸的是我还不能对其他帖子发表评论,但如果有多组报价,Federico Piazza的解决方案将会失败。例如,如果您的文字如下:
String text = "test1 \"hello world!\" test2 \"foobar\" test3";
在这种情况下,它会打印
test1
test3
并完全跳过test2
而是使用模式
Pattern ptrn = Pattern.compile("\".*?\"|([\\w]+)");
?
会导致.*
运算符非贪婪并找到下一个引号而不是最后一个引号。所以基本上复制他的答案你可以做到以下几点。
String text = "test1 \"hello world!\" test2 \"foobar\" test3";
Pattern ptrn = Pattern.compile("\".*?\"|([\\w]+)");
Matcher m = ptrn.matcher(text);
while (m.find()) {
if (m.group(1) != null) {
System.out.println("Text: "+m.group(1));
}
}
答案 2 :(得分:0)
这些动词是告诉正则表达式引擎(在这种情况下为PCRE)你想要丢弃这些匹配的一种非常有用的方法。
Java没有这些动词,但你可以在没有动词(*SKIP)(*F)
的java上使用相同的方法,然后捕获你想要的内容......所以你可以使用:
".*"|([^\W]+)
or
".*"|(\w+)
然后抓取捕获组1中的内容。
String text = "test1 \"hello world!\" test2";
Pattern ptrn = Pattern.compile("\".*\"|([^\\W]+)");
Matcher m = ptrn.matcher(text);
while (m.find()) {
if (m.group(1) != null) {
System.out.println("Text: "+m.group(1));
}
}
<强> IDEOne Demo 强>
这就是众所周知的 discard technique ,您可以放弃所有未捕获的模式并专注于您要捕获的模式,例如,如果您有:
".*"|'.*'|`.*`|([^\W]+)
这将匹配所有模式,但会捕获最后一个
答案 3 :(得分:0)
你想要在引号之外的单词排除尾随空格:
[^"\s]++((?=\s*"[^\s])|(?=\s*$)|(?=[^"]+\s+"))
如果出现以下情况则失败:
因此它仅定期在OP的常规输入上工作。