2017-01-04 61 views
7

我讀其中包含大量信息的文件的特定詞的句子如下所示:正則表達式來排除其中包含的Java

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)(.*) 我想提取所有的字符串,其不包含「布爾可見性=假」 但我的一個正在返回所有。 我也嘗試了很多類似的帖子,但結果與我的類似,請建議一種方法。

解決方案:(?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

當你說「要提取的所有字符串」,你的意思是提取所有類型DW _...和結束之間的類型? –

+0

是的,有很多這樣的表達式,我只需要提取那些不包含「boolean visible = false」的表達式 – SOP

回答

2

你可以使用這個表達式

(\s*boolean visible = false)|(.*) 

DEMO

這基本上定義了2個捕獲組

  1. 第一捕獲組(\s*boolean visible = false)將捕獲boolean visible = false

  2. 第二捕獲組(.*)將捕獲除第一捕獲組捕獲的所有其他數據外的所有數據。

現在,當您提取它時,只需捕獲第二組並忽略第一組。


編輯

下面是澄清的例子:

在這個例子中,

  • getOriginalFileContents()方法獲取該文件的內容如圖所示的程序。
  • 請注意,我們如何獲得這兩個組,但忽略第一組並僅打印第二組。

查看輸出,該輸出沒有該行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; 
    } 
} 
+0

它通過排除「boolean visible = false」來捕獲這兩個字符串,我想排除包括「boolean visible = false」的完整表達式 – SOP

+0

@ShashiRanjan這就是概念。打印時,我們會收到兩個組,但忽略第一組。看到編輯答案。 –

+0

如果兩個表達式「boolean visible = false」,那麼匹配器(2)返回的表達式不包括「boolean visible = false」 – SOP

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).)+$ 

這將匹配整個(非空)行如果 - 只 - 如果它不包含"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(""); 
2
type dw_\d\s+(.*?)\s+within(.*)\n(?!\s*boolean visible = false\s*)[\s\S]*?\s+end type 

嘗試this.See演示。

https://regex101.com/r/Heex8W/1

+0

特別感謝你。它是你的正則表達式,它引導我獲得解決方案 – SOP