Schrift
[thread]8544[/thread]

RegEx Problem



<< |< 1 2 >| >> 14 Einträge, 2 Seiten
Gast Gast
 2006-12-01 16:06
#72142 #72142
Hallo,

Ich hab grad ein Brett vorm Kopf und komm nicht weiter. Also gegeben sei ein String (aus einem SQL-Codegenerator)
Code: (dl )
my $s = "bla bla and table.column like 'inhalt' and bla bla bla";

Nun brauche ich eine RE, der mir den String folgendermassen in 4 Teile zerlegt, etwa so:
Code: (dl )
1
2
my @l = $s =~ /^(.*?)([\w.]*) like ('.*')(.*)$/;
print join "\n", @l;

Ich bekommen dann folgende (korrekte) Ausgabe:
Code: (dl )
1
2
3
4
bla bla and
table.column
'inhalt'
and bla bla bla


Nun zu meinem Problem: Der Quellstring kann auch z.B. so aussehen:
Code: (dl )
my $s = "bla bla and table.column like 'in''ha''lt' and bla bla bla";

(Da in SQL ' mit '' escaped werden). Ich bräuchte dann folgende Ausgabe:
Code: (dl )
1
2
3
4
bla bla and
table.column
'in''ha''lt'
and bla bla bla


Vermutlich ganz einfach, aber ich kriegs nicht hin..
bloonix
 2006-12-01 16:43
#72143 #72143
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
[quote=Guest,01.12.2006, 15:06]Ich bräuchte dann folgende Ausgabe:
Code: (dl )
1
2
3
4
bla bla and
table.column
'in''ha''lt'
and bla bla bla
[/quote]
Also bei mir ist die Ausgabe genauso wie du Sie brauchst, ohne das ich
deine Regex verändert habe!

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
use strict;
use warnings;

my $a = "bla bla and table.column like 'inhalt' and bla bla bla";
my $b = "bla bla and table.column like 'in''ha''lt' and bla bla bla";

my @a = $a =~ /^(.*?)([\w.]*) like ('.*')(.*)$/;
print join("\n", @a), "\n";

print "-------------------------------------------\n";

my @b = $b =~ /^(.*?)([\w.]*) like ('.*')(.*)$/;
print join("\n", @b), "\n";


bla bla and
table.column
'inhalt'
and bla bla bla
-------------------------------------------
bla bla and
table.column
'in''ha''lt'
and bla bla bla


Scheint ja also alles ok zu sein? Oder? :)\n\n

<!--EDIT|opi|1164984313-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
badblock
 2006-12-01 17:05
#72144 #72144
User since
2006-06-01
10 Artikel
BenutzerIn
[default_avatar]
Ups, ich habe ein etwas doofes Beispiel gewählt, also der String kann auch so aussehen:
Code: (dl )
my $s= "bla bla and table.column like 'in''ha''lt' and bla = 'bla'";

und als Ausgabe bräuchte ich dann
Code: (dl )
1
2
3
4
bla bla and
table.column
'in''ha''lt'
and bla = 'bla'
bloonix
 2006-12-01 18:37
#72145 #72145
User since
2005-12-17
1615 Artikel
HausmeisterIn
[Homepage]
user image
Code: (dl )
/^(.*?)([\w.]*) like ('.*')(\s*and.*)$/


Aber das hilft dir wohl auch nur für dieses eine Beispiel weiter...
Vielleicht ist es dir möglich, irgendwie mit split / and / zu arbeiten.
Statt des "and" in der Splitanweisung muss natürlich was intelligenteres
her.\n\n

<!--EDIT|opi|1164991093-->
What is a good module? That's hard to say.
What is good code? That's also hard to say.
One man's Thing of Beauty is another's man's Evil Hack.
PerlProfi
 2006-12-01 20:14
#72146 #72146
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Ich weiß nicht wie table.column aussehen kann, wenn es nur Buchstaben sind, sollte das hier gehen:
Code: (dl )
@a = $a =~ /^(.+? and )(\w+\.\w+) like ('.*?')( and .*)$/;

Ansonsten kannst du ja den entsprechenden Teil mit etwas anderem ersetzen.

MfG PerlProfi
badblock
 2006-12-01 23:06
#72147 #72147
User since
2006-06-01
10 Artikel
BenutzerIn
[default_avatar]
[quote=opi,01.12.2006, 17:37]
Code: (dl )
/^(.*?)([\w.]*) like ('.*')(\s*and.*)$/


Aber das hilft dir wohl auch nur für dieses eine Beispiel weiter...
Vielleicht ist es dir möglich, irgendwie mit split / and / zu arbeiten.
Statt des "and" in der Splitanweisung muss natürlich was intelligenteres
her.[/quote]
Quote
Code: (dl )
/^(.*?)([\w.]*) like ('.*')(\s*and.*)$/


Das ist leider auch nicht ganz wasserdicht, denn:
anstatt "and" kann auch ein "or" kommen (oder auch gar nichts mehr),
Also noch ein Beispielstring:
Code: (dl )
some.col = 4 and my.col like 'a''b''c' and another.col = 'xy' and a.b = 3

Hier soll das Ergegnis so aussehen:
Code: (dl )
1
2
3
4
1: some.col = 4 and
2: my.col
3: 'a''b''c'
4: and another.col = '123' and a.b = 3


Wenn ichs mir genau überlege, ist das aber noch komplizierter, denn es könne ja auch so einen Fall geben:
Code: (dl )
some.col like 'ab'' cd.ef like ' and my.col like 'xyz'


Gewünschtes Ergebnis:
Code: (dl )
1
2
3
4
1: some.col like 'ab'' cd.ef like ' and
2: my.col
3: 'xyz'
4: (undef)


Um das wirklich wasserdicht zu bekommen, muss ich einen SQL-Parser neu erfinden, oder?
PerlProfi
 2006-12-01 23:54
#72148 #72148
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Ich habe für dein letztes Beispiel einfach noch ein ? an meine RegEx drangehängt und es hat funktioniert:
Code: (dl )
@a = $a =~ /^(.+? and )(\w+\.\w+) like ('.*?')( and .*)?$/;


Darf der erste Teil auch weggelassen werden, schreibst du auch da noch ein ? vor:
Code: (dl )
@a = $a =~ /^(.+? and )?(\w+\.\w+) like ('.*?')( and .*)?$/;


Oder wo genau ist das Problem?

MfG PerlProfi
PerlProfi
 2006-12-02 00:00
#72149 #72149
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Hier mal ein Beispiel Skript:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/perl
use strict;
use warnings 'all';

my $a = "my.col like 'xyz'";
# oder "irgendwas and table.column like 'irgendwas' and irgendwas"
# oder "table.column like 'irgendwas' and irgendwas"
# oder "irgendwas and table.column like 'irgendwas'"

@a = $a =~ /^(.+? and )?(\w+\.\w+) like ('.*?')( and .*)?$/;

for (1..@a)
{
print "$_: ". ($a[$_-1] or "(undef)") ."\n";
}


Ergebnis:
Code: (dl )
1
2
3
4
1: (undef)
2: my.col
3: 'xyz'
4: (undef)


MfG PerlProfi
badblock
 2006-12-04 10:22
#72150 #72150
User since
2006-06-01
10 Artikel
BenutzerIn
[default_avatar]
So, nun ist mir (als ich mich eigentlich mit etwas ganz anderem beschäftigt habe :-) ) eine Lösung einfallen, die ziemlich gut funktioniert:

Code: (dl )
/^(.*?)([\w.]+) like ('(?:''|[^'])*')(.*)$/


d.h. nach dem like kann ein beliebiger String stehen, der durch ein EINFACHES Hochkomma begrenzt ist. (Zwei Hochkommas hintereinander stehen in SQL ja für ein "escape'tes"-Hochkomma).
PerlProfi
 2006-12-04 18:00
#72151 #72151
User since
2006-11-29
340 Artikel
BenutzerIn
[default_avatar]
Ich verstehe leider immer noch nicht was an meiner RegEx falsch sein soll?
<< |< 1 2 >| >> 14 Einträge, 2 Seiten



View all threads created 2006-12-01 16:06.