wyrażenie regularne

0

Witam

Nie mogę sobie poradzić. Otóż chciałem wpisać takie wyrażenie regularne : "{.}" żeby odnajdowało mi bloki w programie c# ale podobno znak "{" i "}" to znaki sp0ecjalne więć muszę jakoś inaczej. Gdy napiszę "{.}" studio się czepia że niewłaściwa sekwencja. Do czego jest @ ? Nie wiem jak zbudować ten regex. :|

0

niestety nie mam teraz dostępu do kompilatora ale któraś z wersji możliwe, że zadziała, wiem na pewno, że aby uzyskać znak " trzeba go użyć jako "" sprawdź więc te kombinacje :

string Warunek = @"{(.?)}";
string Warunek = @"{{(.
?)}}";
string Warunek = @"{(.*?)}";

MatchCollection WYNIK = Regex.Matches(ZMIENNA TEKSTOWA, Warunek, RegexOptions.Multiline);

0

SORRY żadna z tych nie pasuje

0

Albo tak:
@"{.}"
albo
"\{.
\}"

Znak \ jest znakiem ucieczki wyrazen i ciagu znakow jednoczesnie. @ wylacza traktowanie go jako znak specjalny ciagu znakow, wiec ciagle musisz go dac, zeby "escapowac" { lub }. Te znaki sa znakami specjalnymi tylko wyrazen.

0

Dzięki ale to wszystko już próbowałem i nic.Jak mawiał Einstein wszystko powinno być możliwie proste ale nie za proste.Uruchomiłem program RegexBuddy jest to program wizualizujący efekty regexu.Udało mi się znaleźć coś takiego:

[a-zA-Z0-9()=":/@*&?_.\n]*(.*)

ale nie wiem czy mi to pomoże.Gdy dodaję "{" wszystko się niweczy. Czy zna ktoś właściwą drogę?

0

Tak więc kolego, to co podałem ja na początku w 3 przykładzie i to co potwierdził Johny

string Warunek = @"\{(.*?)\}";

jest poprawne i zwraca dobrze podane wartości. Kłopot zaczyna się wtedy, gdy masz "troszkę inaczej" poukładany kod. Już wyjaśniam.

Pod pojęciem troszkę inaczej mam na myśli (standardowy) kod np.

class A
{
    public function B()
    {
    }
}

w tym przypadku wyrażenie regularne zwróci wartość public function B() {
co jest oczywiście z punktu widzenia programu poprawne, gdyż regex miał wyciągać dane między { a }

Wyrażenie to zadziała poprawnie dla takiego kodu

public function A()
{
KOD FUNKCJI
}

public function B()
{
KOD FUNKCJI2
}

w takim wypadku otrzymamy listę gdzie 0 elementem będzie KOD FUNKCJI a 1 elementem KOD FUNKCJI2.

Być może są na to lepsze sposoby, nawet na pewno są, lecz ja również zaczynam przygodę z programowaniem i możliwe, że Ci to pomoże. Ja bym po prostu puścił coś takiego

List<int> Poczatek = new List<int>();
List<int> Koniec = new List<int>();

for(int i=0; i < kod.Length;i++)
{
if( kod[i] == "{" ) Poczatek.Add(i);

if( kod[i] == "}" ) Koniec.Add(i);
}

Następnie odpowiednie segmenty kodu wyciągniesz czytając Początek od końca i Koniec od początku :P
czyli. największy blok kodu, powiedzmy całą funkcję Main otrzymasz w taki sposób (kod jest sprawdzany od góry do dołu)

Największy_blok_kodu = kod (od Poczatek[0] do Koniec[Koniec.Count])

zaś
Najmniejszy kawałek kodu = kod( od Poczatek[Poczatek.Count] , do Koniec[0]);

coraz większe fragmenty kodu (zaczynając od najmniejszego) możesz wydobywać w taki sposób

kod ( Początek[Poczate.Cout --] , Koniec[0 ++] )

Mam nadzieję że choć w dość zagmatwany sposób ale opisałem Ci jak ja bym to zrobił.

0

Dzięki bardzo.Ja znalazłem coś innego:

\{[^\{\}]*\}

to mnie trochę posuwa naprzód ale nadal jestem jeszcze daleko.Dzięki.

1

\{[^\{\}]*\}

To nie podziała.

Wyobraź sobie

class abc
{
    void def()
    {
    }
}

Twój regex (co kolega już pisał) wyciąga wszystko od napotkania znaku '{' do wystąpienia znaku '}', pod warunkiem że nie znajdzie w wyrażeniu znaków { i }.

Kod powyżej <ort>w ogóle </ort>nie zostanie dopasowany.

0

co znaczy ze chcesz odnajdywac bloki w programie, tzn. bardziej zastanawia mnie po co?
bo takich blokow moze byc wiele w roznych przypadkach

namespace xxx {}
class xxx {}
enum xxx {}
if (){}
else {}
while {}
do {} while ()
for() {}
switch (){}
ale mozna takze taki blok wpisac sobie od tak w kodzie
void MyMethod()
{
  var foo1 = new SomeObj();
  {
    // block 1
    int i=0;
  }
  {
    // block 2
    int i=1;
  }
}

a to nie wszystko
wiec moze lepiej powiedz jaki masz cel, moze jest lepsze rozwiazanie

0

Nie wiem, czy we wszystkich przypadkach można użyć wyrażeń regularnych...
Na przykład taki kod:

int fun(){
  string a = " \" hahahahaha } hahahahaha";
  char b = '}';
  a = "'";
  b = '"';
}

Na pewno byłoby tutaj trudnym zadaniem napisać wyrażenie regularne wyciągające całą zawartość między nawiasami.
Co do pozostałych - trzeba byłoby jakoś zliczać nawiasy otwierające i zamykające i skończyć, gdy liczba_otwierających = liczba_zamykających. Tylko nie wiem, czy da się tak w wyrażeniach regularnych...

1

trzeba byłoby jakoś zliczać nawiasy otwierające i zamykające i skończyć, gdy liczba_otwierających = liczba_zamykających. Tylko nie wiem, czy da się tak w wyrażeniach regularnych...

A nie prościej rekurencyjnie?

PS. Zliczać nawiasów otwierających i zamykających regexem się nie da. Nie jestem jednak pewien czy jakiś zakręcony regex nie rozwiąże twojego problemu, próbuj :)

0

Da sie chyba takie wyrazenie zrealizowac, ale bedzie duzo bardziej skomplikowane niz zwykle przechodzenie po stringu czy to rekurencyjne czy z zastosowaniem stosu.

0

a ja ponowie pytanie co hop666 chcesz uzyskac? tzn. w jakim celu chcesz te bloki kodu wyciagac?
bo jesli chcesz informacje o klasach, metodach, polach etc. to sa latwiejsze sposoby

tak na prawde aby zrobic to w calosci poprawnie musialbyc napisac parser kodu c#, czyli taki element kompilatora :)
a w tym celu poszukaj i poczytaj informacji o teorii automatow i jezykow, maszyny turinga, jezyki i gramatyki etc. same fajne rzeczy :D

1

@up - jest dużo prostszych sposobów, np. każdy obiekt, metoda, przestrzeń nazw, etc udostępnia informacje o sobie - dla pól jest to na przykład metoda GetType() zwracająca kompletny zestaw informacji.

A kompilatora można używać bezpośrednio z kodu - widziałem nawet przykład programu w C# potrafiącego kompilować kod C#.

0
MSM napisał(a)

A kompilatora można używać bezpośrednio z kodu - widziałem nawet przykład programu w C# potrafiącego kompilować kod C#.

Zwlaszcza, ze kompilator jest dostepny jako klasa i skompilowanie kodu w postaci tekstu to 4 linijki :P

1 użytkowników online, w tym zalogowanych: 0, gości: 1