我正在阅读一个包含大量信息的文件,如下所示:
type dw_3 from u_dw within w_pg6p0012_01
boolean visible = false
integer x = 1797
integer y = 388
integer width = 887
integer height = 112
integer taborder = 0
boolean bringtotop = true
string dataobject = "d_pg6p0012_14"
end type
type dw_3 from u_dw within w_pg6p0012_01
integer x = 1797
integer y = 388
integer width = 887
integer height = 112
integer taborder = 0
boolean bringtotop = true
string dataobject = "d_pg6p0012_14"
end type
我制作了正则表达式:(?i)type dw_\d\s+(.*?)\s+within(.*?)\s+(?!boolean visible = false)(.*)
我想提取所有不包含的字符串" boolean visible = false"
但我的一个人正在全部归来。
我也在堆栈上尝试了很多类似的帖子,但结果与我的相似,请提示一下。
解决方案:(?i)type\\s+dw_(\\d+|\\w+)\\s+from\\s+.*?within\\s+.*?\\s+(string|integer)?\\s+.*\\s+.*\\s+.*\\s+.*?\\s+.*?\\s+.*?\\s*string\\s+dataobject\\s+=\\s+(.*?)\\s+end\\s+type")
这在正则表达式检查器上运行良好,但是当我在java上尝试它时,它继续运行而不提供任何输出
答案 0 :(得分:8)
如果您使正则表达式与"boolean visible = false"
匹配,然后排除那些包含匹配项的行,那么它将更多更容易(并且更具可读性)
Pattern pattern = Pattern.compile("boolean visible = false");
Files.lines(filepath)
.filter(line -> !pattern.matcher(line).find()) // note the "!"
.forEach(/* do stuff */);
备注:强>
Files#lines(String)
,所以没有必要在正则表达式中拆分单独的行。这已经为我们完成了。Matcher#find()
方法返回给定的字符序列
包含正则表达式中任何位置的匹配项。我相信这就是你想要的。编辑:
现在,如果你真的想要使用纯正则表达式,那么试试这个:
^((?!boolean visible = false).)+$
这将匹配整个(非空)行if-and-only-如果它内的任何地方都不包含"boolean visible = false"
。没有花哨的反向引用/捕获组语义来提取所需的文本。
在此处查看单元测试证明:https://regex101.com/r/dbzdMB/1
编辑#2:
或者,如果您要做的只是获取没有任何"boolean visible = false"
的文件文本,那么您可以简单地用空字符串替换该目标字符串的每个实例。
Pattern pattern = Pattern.compile("boolean visible = false");
Matcher matcher = pattern.matcher(fileAsCharSequence); // e.g. StringBuilder
String output = matcher.replaceAll("");
答案 1 :(得分:2)
您可以使用此RegEx
(\s*boolean visible = false)|(.*)
这基本上定义了2个捕获组
第一个捕获组(\s*boolean visible = false)
将捕获boolean visible = false
。
第二个捕获组(.*)
将捕获除第一个捕获组捕获的所有内容之外的其他所有内容。
现在,当您提取它时,只需捕获第二组并忽略第一组。
修改强>
以下是澄清的例子:
在此示例中,
请参阅输出,该输出没有该行boolean visible = false
。
<强>输出强>
type dw_3 from u_dw within w_pg6p0012_01
integer x = 1797
integer y = 388
integer width = 887
integer height = 112
integer taborder = 0
boolean bringtotop = true
string dataobject = "d_pg6p0012_14"
end type
type dw_3 from u_dw within w_pg6p0012_01
integer x = 1797
integer y = 388
integer width = 887
integer height = 112
integer taborder = 0
boolean bringtotop = true
string dataobject = "d_pg6p0012_14"
end type
Java实施
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTut3 {
public static void main(String args[]) {
String file = getOriginalFileContents();
Pattern pattern = Pattern.compile("(\\s*boolean visible = false)|(.*)");
Matcher matcher = pattern.matcher(file);
while (matcher.find()) {
//System.out.print(matcher.group(1)); //ignore this group
if (matcher.group(2) != null) System.out.println(matcher.group(2));
}
}
//this method just get's the file contents as displayed in the
//question.
private static String getOriginalFileContents() {
String s = " type dw_3 from u_dw within w_pg6p0012_01\n" +
" boolean visible = false\n" +
" integer x = 1797\n" +
" integer y = 388\n" +
" integer width = 887\n" +
" integer height = 112\n" +
" integer taborder = 0\n" +
" boolean bringtotop = true\n" +
" string dataobject = \"d_pg6p0012_14\"\n" +
" end type\n" +
" \n" +
" type dw_3 from u_dw within w_pg6p0012_01\n" +
" integer x = 1797\n" +
" integer y = 388\n" +
" integer width = 887\n" +
" integer height = 112\n" +
" integer taborder = 0\n" +
" boolean bringtotop = true\n" +
" string dataobject = \"d_pg6p0012_14\"\n" +
" end type";
return s;
}
}
答案 2 :(得分:2)
type dw_\d\s+(.*?)\s+within(.*)\n(?!\s*boolean visible = false\s*)[\s\S]*?\s+end type
试试这个。看看演示。