RegEx Non-Matching Listen

Hallo.

Ich versuche verzweifelt einen RegEx-Ausdruck zu finden, der mir einen
Wortteil, egal ob am Anfang der Zeile oder mittendrin, herausfiltert und
diesen NICHT anzeigt.

Nach dem Einlesen in regulaere Ausdruecke bin ich auf das Listenelement
gestossen. [^...] Das funktionierte auch immer dann, wenn sich der
Ausdruck am Zeilenanfang befand, nicht aber, wenn er mittendrin steht.

Beispiel: Ich moechte alle Zeilen mit der Buchstabenfolge abc ausblenden.
^.*[^(abc)]+.*$
Leider funktioniert dieser Ausdruck nicht.
Auch folgender Ausdruck funktioniert nicht. ^.*[^a]{1}[^b]{1}[^c]{1}.*$
Was mache ich falsch?

Bei Vorschlaegen bitte eine kurze Erklaerung dazu, die Thematik ist fuer
mich neu, danke.

Gruss
Clemens
Clemens Meerbaum [ Do, 09 August 2007 15:43 ] [ ID #1790736 ]

Re: RegEx Non-Matching Listen

Clemens Meerbaum schrieb:
> Hallo.
>
> Ich versuche verzweifelt einen RegEx-Ausdruck zu finden, der mir einen
> Wortteil, egal ob am Anfang der Zeile oder mittendrin, herausfiltert und
> diesen NICHT anzeigt.

Erläuter mal bitte, was 'anzeigen' in deinem Kontext bedeutet und nenne
mal ein paar Beispiele.

Daniel
--
------- _ | _ |_ _. | _ _ _ -------
(_| | (_) |_) (_| | /_ (_) (_)
_| Deine Reisecommunity
--- Reiseblogs - Reisekarte - Reisetipps - http://www.globalzoo.de/ ---
Daniel Fett [ Do, 09 August 2007 15:51 ] [ ID #1790737 ]

Re: RegEx Non-Matching Listen

Daniel Fett schrieb:
> Clemens Meerbaum schrieb:
>>Ich versuche verzweifelt einen RegEx-Ausdruck zu finden, der mir einen
>>Wortteil, egal ob am Anfang der Zeile oder mittendrin, herausfiltert un=
d
>>diesen NICHT anzeigt.
> Erläuter mal bitte, was 'anzeigen' in deinem Kontext bedeutet und nen=
ne
> mal ein paar Beispiele.
> Daniel

Diese Zeile enthaelt die Buchstaben abcdef und soll weggefiltert werden.
Diese Zeile enthaelt andere Buchstaben und soll angezeigt werden.
Diese Zeile enthaelt abc als Wort und soll nicht angezeigt werden.
Diese Zeile bitte anzeigen abdefg
Diese Zeile bitte nicht anzeigen gfdabcijk
Diese Zeile bitte nicht anzeigen abcdefghi

RegEx in Wortform: Filtere nichts ausser *abc* heraus.

Gruss
Clemens
Clemens Meerbaum [ Do, 09 August 2007 15:56 ] [ ID #1790738 ]

Re: RegEx Non-Matching Listen

Hallo, Clemens,

Du (clemens.meerbaum) meintest am 09.08.07:

> Diese Zeile enthaelt die Buchstaben abcdef und soll weggefiltert
> werden.
> Diese Zeile enthaelt andere Buchstaben und soll angezeigt
> werden.
> Diese Zeile enthaelt abc als Wort und soll nicht angezeigt
> werden.
> Diese Zeile bitte anzeigen abdefg
> Diese Zeile bitte nicht anzeigen gfdabcijk
> Diese Zeile bitte nicht anzeigen abcdefghi

> RegEx in Wortform: Filtere nichts ausser *abc* heraus.

Meinst Du "Wort" oder "Zeichenfolge"? Wort: nur Zeile 3 wäre zu filtern.

Zeichenfolge:

grep -v abc $Datei

Viele Gruesse!
Helmut
helmut [ Do, 09 August 2007 16:05 ] [ ID #1790739 ]

Re: RegEx Non-Matching Listen

Am 09.08.2007, 15:56 Uhr, schrieb Clemens Meerbaum
<clemens.meerbaum [at] gmx.de>:

> RegEx in Wortform: Filtere nichts ausser *abc* heraus.

Wiilst du jetzt die ganze Zeile wegfiltern oder nur die Buchstaben? Wie
leigen die Zeilen denn vor (Array, Datei)?

Falls du die ganze Zeile meinst könnt der Denkansatz hier weiterhelfen
(ganz ohne regex):

while (Zeile vorhanden) {
if (substr_count($zeile, 'abc') == 0) echo $zeile;
else continue;
}


Gruß
Chris
Chris Kraft [ Do, 09 August 2007 16:10 ] [ ID #1790741 ]

Re: RegEx Non-Matching Listen

Danke Helmut.
Die -v Option habe ich uebersehen.
Das hilft.

Gruss,
Clemens

Helmut Hullen schrieb:
> Zeichenfolge:
>
> grep -v abc $Datei
Clemens Meerbaum [ Do, 09 August 2007 16:17 ] [ ID #1790742 ]

Re: RegEx Non-Matching Listen

Clemens Meerbaum schrieb:

> Ich versuche verzweifelt einen RegEx-Ausdruck zu finden, der mir einen =

> Wortteil, egal ob am Anfang der Zeile oder mittendrin, herausfiltert un=
d
> diesen NICHT anzeigt.

RegExp zeigen sowieso nicht an.

> Nach dem Einlesen in regulaere Ausdruecke bin ich auf das Listenelement=

> gestossen. [^...] Das funktionierte auch immer dann, wenn sich der
> Ausdruck am Zeilenanfang befand, nicht aber, wenn er mittendrin steht.
>
> Beispiel: Ich moechte alle Zeilen mit der Buchstabenfolge abc ausblende=
n.
> ^.*[^(abc)]+.*$

Dieser Ausdruck heißt:
"Vom Anfang so viele beliebige Zeichen wie möglich, gefolgt von
mindestens einem Zeichen, das nicht '(', 'a', 'b', 'c' oder ')' ist,
gefolgt von beliebig vielen beliebigen Zeichen". Diese Bedingung wird
von jeder Zeichenkette erfüllt, die nicht ausschlkießlich aus den 5
Zeichen '(', 'a', 'b', 'c' oder ')' in beliebiger Zusammensetzung bestehe=
n.

> Was mache ich falsch?

Den Ansatz.

if ( strpos( $str, 'abc' ) !=3D=3D false ) {
// contains 'abc', so ignore
} else {
echo $str;
}

oder kurz:

if ( strpos( $str, 'abc' ) =3D=3D=3D false ) {
echo $str;
}

> Bei Vorschlaegen bitte eine kurze Erklaerung dazu, die Thematik ist fue=
r
> mich neu, danke.

Erklärung steht im Manual. Grundsätzlich: Programmiere geradeaus;
Eleganz kommt später mit der Erfahrung.

MfG
Niels

--
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------
Niels Braczek [ Do, 09 August 2007 16:19 ] [ ID #1790743 ]

Re: RegEx Non-Matching Listen

Danke Helmut.
Die -v Option habe ich uebersehen.
Das hilft.

Gruss,
Clemens

Helmut Hullen schrieb:

> Zeichenfolge:
>
> grep -v abc $Datei
Clemens Meerbaum [ Do, 09 August 2007 16:28 ] [ ID #1790745 ]

Re: RegEx Non-Matching Listen

On Thu, 9 Aug 2007, Clemens Meerbaum wrote:

> RegEx in Wortform: Filtere nichts ausser *abc* heraus.

In der Regel wird man einen RegEx für *abc* schreiben und das Programm
drumrum so stricken, dass alles andere durchkommt.

Wenn man aber den Sport hat, einen RegEx zu schreiben, der *abc* gerade
nicht erfasst, geht man über den zugehörigen Automaten und dreht den um
wie in
http://www.lrz-muenchen.de/services/schulung/unterlagen/regu l/regul-12.html#publish4.1.1.0.0.0
beschrieben.

Ein etwas komplizierteres Beispiel steht in
..../regul-14.html#publish4.3.4.0.0.0 . Viel Spaß!

Diese Beschreibungen sind nicht für eine bestimmte Programmiersprache
wie PHP gemacht, sondern für RegEx ganz allgemein.

--
Helmut Richter
Helmut Richter [ Do, 09 August 2007 16:31 ] [ ID #1790746 ]

Re: RegEx Non-Matching Listen

Niels Braczek schrieb:
> RegExp zeigen sowieso nicht an.
>>^.*[^(abc)]+.*$
>
> Dieser Ausdruck heißt:
> "Vom Anfang so viele beliebige Zeichen wie möglich, gefolgt von
> mindestens einem Zeichen, das nicht '(', 'a', 'b', 'c' oder ')' ist,
> gefolgt von beliebig vielen beliebigen Zeichen". Diese Bedingung wird
> von jeder Zeichenkette erfüllt, die nicht ausschlkießlich aus den 5=

> Zeichen '(', 'a', 'b', 'c' oder ')' in beliebiger Zusammensetzung beste=
hen.

Das war einer meiner Denkfehler. Ich habe nicht daran gedacht, dass die
Klammern innerhalb des Listenelements ordinaere Zeichen sind.

>>Was mache ich falsch?
>
> Den Ansatz.
> if ( strpos( $str, 'abc' ) =3D=3D=3D false ) {
> echo $str;
> }

Ja klar. Das geht in jedem Fall. Nun habe ich aber schon einige
Matching-Pattern, da waere es halt schoen, das Non-Matching auch mit
RegExp zu loesen.

> Eleganz kommt später mit der Erfahrung.
Wohl war. Aber gibt es denn ueberhaupt einen RegExp Ausdruck, der das
Problem loest? Unter Linux gibt es ja, wie ich gerade gelernt habe, die
-v Option. Vielleicht weil es keine Non-Matching-Zeichenfolgen gibt?
>
> MfG
> Niels

Gruss,
Clemens
Clemens Meerbaum [ Do, 09 August 2007 16:38 ] [ ID #1790750 ]

Re: RegEx Non-Matching Listen

Helmut Richter schrieb:
> http://www.lrz-muenchen.de/services/schulung/unterlagen/regu l/regul-14.html#publish4.3.4.0.0.0

Ok, es geht. Damit ist meine Frage nach der Machbarkeit beantwortet.
Ja, und ich werde es nicht so machen. Das habe ich auch verstanden.

Danke.
Gruss,
Clemens
Clemens Meerbaum [ Do, 09 August 2007 16:54 ] [ ID #1790751 ]

Re: RegEx Non-Matching Listen

Clemens Meerbaum schrieb:
> Niels Braczek schrieb:

> Ja klar. Das geht in jedem Fall. Nun habe ich aber schon einige
> Matching-Pattern, da waere es halt schoen, das Non-Matching auch mit
> RegExp zu loesen.
>
>> Eleganz kommt später mit der Erfahrung.

> Wohl war. Aber gibt es denn ueberhaupt einen RegExp Ausdruck, der das
> Problem loest?

Weiß ich nicht - braucht man auch nicht. preg_match liefert nur die
Information, ob das Muster passt oder nicht. Damit ist alles machbar.

if ( preg_match( '~abc~', $str ) ) {
echo '$str enthält "abc"';
}

oder das Gegenteil:

if ( !preg_match( '~abc~', $str ) ) {
echo '$str enthält kein "abc"';
}

Da ist ein Negativ-Pattern nicht erforderlich.

MfG
Niels

--
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------
Niels Braczek [ Fr, 10 August 2007 01:53 ] [ ID #1791991 ]

Re: RegEx Non-Matching Listen

Clemens Meerbaum schrieb:
> Daniel Fett schrieb:
>> Clemens Meerbaum schrieb:
>>> Ich versuche verzweifelt einen RegEx-Ausdruck zu finden, der mir einen
>>> Wortteil, egal ob am Anfang der Zeile oder mittendrin, herausfiltert und
>>> diesen NICHT anzeigt.
>> Erläuter mal bitte, was 'anzeigen' in deinem Kontext bedeutet und nenne
>> mal ein paar Beispiele.
>> Daniel
>
> Diese Zeile enthaelt die Buchstaben abcdef und soll weggefiltert werden.
> Diese Zeile enthaelt andere Buchstaben und soll angezeigt werden.
> Diese Zeile enthaelt abc als Wort und soll nicht angezeigt werden.
> Diese Zeile bitte anzeigen abdefg
> Diese Zeile bitte nicht anzeigen gfdabcijk
> Diese Zeile bitte nicht anzeigen abcdefghi
>
> RegEx in Wortform: Filtere nichts ausser *abc* heraus.

<?php
$Text='0 abc
1 Diese Zeile enthaelt die Buchstaben abcdef und soll weggefiltert werden.
2 Diese Zeile enthaelt andere Buchstaben und soll angezeigt werden.
3 Diese Zeile enthaelt abc als Wort und soll nicht angezeigt werden.
4 Diese Zeile bitte anzeigen abdefg
5 Diese Zeile bitte nicht anzeigen gfdabcijk
6 Diese Zeile bitte nicht anzeigen abcdefghi';

$RegEx0 = '/(?!(?:^.*abc.*$))(^.*$)/Um';
$RegEx1 = '/(?!(?:^.*abc.*$))(^.*$)|(^.*)$/Um';

preg_match_all ($RegEx0, $Text, $Treffer);
echo implode ($Treffer[1],"\r\n");
?>

RegEx1 eignet sich für Lückentexte oder um die Zeilennummern der gefundenen
und gefilterten Zeilen herauszufinden.

viele grüße
ralph
rkhbng [ Fr, 10 August 2007 03:36 ] [ ID #1791992 ]

Re: RegEx Non-Matching Listen

Ralph 'rkhb' Bauer schrieb:

> $RegEx0 =3D '/(?!(?:^.*abc.*$))(^.*$)/Um';
> $RegEx1 =3D '/(?!(?:^.*abc.*$))(^.*$)|(^.*)$/Um';

Ich habe irgendwo im Hinterkopf, dass Look-ahead nur mit Mustern fester
Länge funktioniert ...

MfG
Niels

--
| http://www.kolleg.de =B7 Das Portal der Kollegs in Deutschland |
| http://www.bsds.de =B7 BSDS Braczek Software- und DatenSysteme |
| Webdesign =B7 Webhosting =B7 e-Commerce =B7 Joomla! Content Management =
|
------------------------------------------------------------ ------
Niels Braczek [ Fr, 10 August 2007 06:33 ] [ ID #1791993 ]

Re: RegEx Non-Matching Listen

Hallo,

evtl. ist

$text = implode("\n", preg_grep("/abc/", explode("\n",$text),
PREG_GREP_INVERT));

Wobei die explode/implode nur dazu dienen, den Text an den Zeilenenden
aufzusplitten und wieder zusammenzusetzen.

Alexander

Clemens Meerbaum schrieb:
> Diese Zeile enthaelt die Buchstaben abcdef und soll weggefiltert werden.
> Diese Zeile enthaelt andere Buchstaben und soll angezeigt werden.
> Diese Zeile enthaelt abc als Wort und soll nicht angezeigt werden.
> Diese Zeile bitte anzeigen abdefg
> Diese Zeile bitte nicht anzeigen gfdabcijk
> Diese Zeile bitte nicht anzeigen abcdefghi
>
> RegEx in Wortform: Filtere nichts ausser *abc* heraus.
>
> Gruss
> Clemens
>
Alexander Fleischer [ Fr, 10 August 2007 09:54 ] [ ID #1791995 ]

Re: RegEx Non-Matching Listen

Niels Braczek schrieb:
> Ralph 'rkhb' Bauer schrieb:
>
>> $RegEx0 = '/(?!(?:^.*abc.*$))(^.*$)/Um';
>> $RegEx1 = '/(?!(?:^.*abc.*$))(^.*$)|(^.*)$/Um';
>
> Ich habe irgendwo im Hinterkopf, dass Look-ahead nur mit Mustern fester
> Länge funktioniert ...

Laut Manual nur lookbehind assertions:

"The contents of a lookbehind assertion are restricted such that all the
strings it matches must have a fixed length."
http://www.php.net/manual/en/reference.pcre.pattern.syntax.p hp unter
'Assertions'.

Ein solcher Hinweis fehlt bei lookahead assertions.

Ob's funktioniert, kann man bei meinem Beispiel ja leicht nachprüfen, da ich
einen vollständigen, funktionierenden Block gepostet habe.

viele grüße
ralph
rkhbng [ Fr, 10 August 2007 10:47 ] [ ID #1792007 ]

Re: RegEx Non-Matching Listen

Clemens Meerbaum wrote:
> Beispiel: Ich moechte alle Zeilen mit der Buchstabenfolge abc ausblenden.
> ^.*[^(abc)]+.*$
> Leider funktioniert dieser Ausdruck nicht.
> Auch folgender Ausdruck funktioniert nicht. ^.*[^a]{1}[^b]{1}[^c]{1}.*$
> Was mache ich falsch?
>
> Bei Vorschlaegen bitte eine kurze Erklaerung dazu, die Thematik ist fuer
> mich neu, danke.

Sorry, ich bin ein wenig spät in den Thread
eingestiegen, möchte aber dennoch meinen
Senf dazugeben. Ich würde es folgender-
massen machen:

....
$alle_zeilen = array(
'Diese Zeile enthaelt die Buchstaben abcdef und soll weggefiltert werden.',
'Diese Zeile enthaelt andere Buchstaben und soll angezeigt werden.',
'Diese Zeile enthaelt abc als Wort und soll nicht angezeigt werden.',
'Diese Zeile bitte anzeigen abdefg',
'Diese Zeile bitte nicht anzeigen gfdabcijk',
'Diese Zeile bitte nicht anzeigen abcdefghi ');

{ # Variante 1 - preg_grep + pattern_invert
$schlecht='abc';
$gute_zeilen = preg_grep( '/abc/', $alle_zeilen, PREG_GREP_INVERT);
print_r($gute_zeilen);
}

{ # Variante 2 - preg_grep + 'non-match' pattern
$schlecht='abc';
$gute_zeilen = preg_grep( '/^(?:.(?!abc))*$/', $alle_zeilen);
print_r($gute_zeilen);
}
....


Viele Grüße

Mirco
Mirco Wahab [ Fr, 10 August 2007 21:37 ] [ ID #1792042 ]

Re: RegEx Non-Matching Listen

Mirco Wahab wrote:
> $gute_zeilen = preg_grep( '/^(?:.(?!abc))*$/', $alle_zeilen);

uups, der Punkt muss natürlich *nach* dem lookahead kommen,
da ja sonst ein abc am Zeilenanfang durch die Lappen gehen
würde ...

$gute_zeilen = preg_grep( '/^(?:(?!abc).)*$/', $alle_zeilen);

Sorry,

M.
Mirco Wahab [ Fr, 10 August 2007 21:40 ] [ ID #1792043 ]
PHP » de.comp.lang.php.misc » RegEx Non-Matching Listen

Vorheriges Thema: geladenes Bild zentrieren
Nächstes Thema: Zahlencodes eingeben