2017-01-04 19 views
7

Czytam plik zawierający wiele informacji jak pokazano poniżej:regex wykluczyć zdanie, które zawiera określone słowo w 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 

zrobiłem regex: (?i)type dw_\d\s+(.*?)\s+within(.*?)\s+(?!boolean visible = false)(.*) chcę wyodrębnić wszystkie ciągi, które nie zawierają "boolean visible = false" , ale mój zwraca wszystkie. Próbowałem również wielu podobnych stanowisk na stosie, ale wynik jest podobny do mojego, sugeruj sposób.

rozwiązanie: (?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")

to działa dobrze na sprawdzający regex ale gdy próbowałem go na java to ciągle działa bez podania wyjście

+0

Kiedy mówisz „chcą, aby wyodrębnić wszystkie sznurki”, masz na myśli wydobyć wszystko od typu i rodzaju DW _... końcowego? –

+0

Tak, istnieje wiele takich wyrażeń, z których muszę wyodrębnić tylko te wyrażenia, które nie zawierają "boolean visible = false" – SOP

Odpowiedz

2

Można użyć tego wyrażenia regularnego

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

DEMO

To zasadniczo definiuje 2 grupy przechwytujące

  1. Pierwsza grupa przechwytująca (\s*boolean visible = false) złapie boolean visible = false.

  2. Druga grupa przechwytywania (.*) przechwytuje wszystko inne oprócz wszystkich przechwytywanych przez pierwszą grupę przechwytywania.

Teraz, gdy go wyodrębniamy, wystarczy przechwycić drugą grupę i zignorować pierwszą.


Edit

Oto przykład dla wyjaśnienia:

W tym przykładzie

  • getOriginalFileContents() metoda pobiera zawartość pliku, jak pokazano w programie.
  • Zobacz, jak otrzymujemy obie grupy, ale ignorujemy pierwszą grupę i drukujemy tylko drugą.

Zobacz dane wyjściowe, które nie mają tej linii boolean visible = false.

Wyjście

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 

Wdrożenie 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

Przechwytuje oba ciąg znaków po prostu wykluczając "boolean visible = false", chcę wykluczyć pełne wyrażenie, które zawiera "boolean visible = false" – SOP

+0

@ShashiRanjan, to jest pojęcie. Dostajemy obie grupy, ale ignorujemy pierwszą podczas drukowania. Zobacz edytowaną odpowiedź. –

+0

jeśli oba wyrażenia "boolean visible = false" to również matcher (2) zwraca wyrażenie z wyłączeniem "boolean visible = false" – SOP

8

Będzie znacznie łatwiejsze (i bardziej czytelny), jeśli uczynić regex dopasować "boolean visible = false" a następnie wykluczyć te linie, które zawierają dopasowanie do niego.

Pattern pattern = Pattern.compile("boolean visible = false"); 

Files.lines(filepath) 
    .filter(line -> !pattern.matcher(line).find()) // note the "!" 
    .forEach(/* do stuff */); 

Uwagi:

  • Ponieważ używamy Files#lines(String), nie jest konieczne, aby rozpadają oddzielne linie w regex. To już zrobiono dla nas.
  • Metoda Matcher#find() zwraca, czy podana sekwencja znaków zawiera dopasowanie dla wyrażeń regularnych w dowolnym miejscu. Wierzę, że tego właśnie chcesz.

EDIT:

Teraz, jeśli tylko naprawdę zdecydowani przy użyciu czystego regex, a następnie spróbuj tego:

^((?!boolean visible = false).)+$ 

To będzie pasował cała (niepusty) linia if-and-only-if if does not include "boolean visible = false" w dowolnym miejscu w środku. Bez wyszukanych odsyłaczy wstecznych/semantyki grup przechwytywania potrzebnych do wyodrębnienia pożądanego tekstu.

Zobacz dowodu za pomocą testów jednostkowych tutaj: https://regex101.com/r/dbzdMB/1


EDIT # 2:

Alternatywnie, jeśli wszystko, co staramy się robić to, aby uzyskać tekst plików bez "boolean visible = false", to można po prostu zamień każdą instancję tego docelowego łańcucha na pusty ciąg znaków.

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 

Spróbuj this.See demo.

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

+0

Specjalne podziękowania dla Ciebie. To twój regex, który poprowadził mnie do rozwiązania – SOP