ACHTUNG. Das ist ein Archiv des alten forum.ruby-portal.de. Die aktuelle Mailingliste gibt es auf lists.ruby-lang.org/pipermail/ruby-de.

NOTICE. This is a ready-only copy of the old forum.ruby-portal.de. You can find the current mailing list at lists.ruby-lang.org/pipermail/ruby-de.

Die Programmiersprache Ruby

Blog|

Forum|

Wiki  


Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]

Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 
Autor Nachricht
BeitragVerfasst: 25 Jun 2005, 22:46 
Offline
Interpreter

Registriert: 15 Mär 2005, 19:26
Beiträge: 6142
Wohnort: Karlsruhe
Die neue in Ruby ab Version 1.9 benutzte Mustermaschine Onigurama enthält wesentliche Erweiterungen. Die eine, rekursive Benutzung definierter Gruppen im Muster, erweitert die Möglichkeiten der Muster so extrem, dass man nun eigentlich nicht mehr von Regulären Ausdrücken sprechen dürfte. Da es damit aber augenscheinlich noch ein paar Probleme gibt (oder ich habe mich vertan), will ich hier nicht darauf eingehen - das ist ein anderer Beitrag.

Ich wusste nicht genau wohin mit diesem Beitrag, habe ihn aber erst einmal unter Programmieren plaziert, da es ja darum geht. iGEL oder murphy mögen es gegebenenfalls an eine sinnvollere Stelle packen. Vielleicht kann den Inhalt ja auch Winfried für seine Regex-Intro nutzen oder jemand motzt es fürs Wiki auf.

Schluss mit der Vorrede, ran ans Thema. Es gibt auch andere Musterbeschreibungssprachen als die (Varianten der) Regulären Ausdrücke. Das sind insbesondere jene der Sprachen Snobol4 und Icon.

In beiden Sprachen gibt es die Musterelemente pos(n), rpos(n), tab(n) und rtab(n). Sie sind oft recht nützlich, jedoch in den Regulären Ausdrücken nicht vorhanden. Sie lassen sich jedoch mittels der Erweiterungen Positive Look Ahead und Positive Look Behind nachbilden. Erst mal die Definitionen der oben genannten Musterfunktionen.
  • pos(n)
    Ist wie ^, $, \A, \z und \Z eine Positionsverifikation, die kein Zeichen erkennt. pos(n) zieht genau dann, wenn das nachfolgende Muster an der Position n in der Zeile beginnt (Zeile definiert durch alles von ^ bis $).
  • rpos(n)
    Wie pos(n), nur wird die Position vom Ende der Zeile gerechnet.
  • tab(n)
    Es werden beliebige Zeichen bis zur Position n in der Zeile erkannt, an der dann das restliche Muster aufsetzt. Ist die aktuelle Position schon grösser als n zieht das Muster nicht.
  • rtab(n)
    Wie tab(n), nur wird die Position vom Ende der Zeile gerechnet.

So, nun los mit Teilen, die auch schon unter der alten Mustermaschine gehen, also auch unter Ruby 1.8, weil dafür nur Positive Look Ahead benutzt wird. Zuerst rpos(n).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Muster fuer RPOS(n)
puts "\n>>>>> Muster: /<rpos(10)>test/ <<<<<"
strs = ['...test.....',
'...test......',
'...test.......']
pattern = /(?=.{10}$)test/
puts "Pattern: #{pattern.inspect}"
strs.each do |str|
puts "\nString: '#{str}'"
if (res = str.match(pattern)) then
puts "Match: '#{res}'"
else
puts "+++++ No Match"
end
end
Ergibt

1
2
3
4
5
6
7
8
9
10
11
>>>>> Muster: /<rpos(10)>test/ <<<<<
Pattern: /(?=.{10}$)test/

String: '...test.....'
+++++ No Match

String: '...test......'
Match: 'test'

String: '...test.......'
+++++ No Match

Die folgenden Teile sind nur Variationen von rpos(n) für gleiner oder gleich ...


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Muster fuer RPOS(<=n)
puts "\n>>>>> Muster: /<rpos(<=10)>test/ <<<<<"
strs = ['...test.....',
'...test......',
'...test.......']
pattern = /(?=.{,10}$)test/
puts "Pattern: #{pattern.inspect}"
strs.each do |str|
puts "\nString: '#{str}'"
if (res = str.match(pattern)) then
puts "Match: '#{res}'"
else
puts "+++++ No Match"
end
end
Ergibt

1
2
3
4
5
6
7
8
9
10
11
>>>>> Muster: /<rpos(<=10)>test/ <<<<<
Pattern: /(?=.{,10}$)test/

String: '...test.....'
Match: 'test'

String: '...test......'
Match: 'test'

String: '...test.......'
+++++ No Match

... beziehungsweise grösser oder gleich


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Muster fuer RPOS(>=n)
puts "\n>>>>> Muster: /<rpos(>=10)>test/ <<<<<"
strs = ['...test.....',
'...test......',
'...test.......']
pattern = /(?=.{10,}$)test/
puts "Pattern: #{pattern.inspect}"
strs.each do |str|
puts "\nString: '#{str}'"
if (res = str.match(pattern)) then
puts "Match: '#{res}'"
else
puts "+++++ No Match"
end
end
Ergibt

1
2
3
4
5
6
7
8
9
10
11
>>>>> Muster: /<rpos(>=10)>test/ <<<<<
Pattern: /(?=.{10,}$)test/

String: '...test.....'
+++++ No Match

String: '...test......'
Match: 'test'

String: '...test.......'
Match: 'test'

Das Musterelement pos(n) benötigt Positive Look Behind, ist also erst ab Ruby 1.9 implementierbar. Die oben als Ergänzung aufgeführten Funktionen, die gleiner oder gleich oder grösser oder gleich bereitstellen, sind für pos(n) nicht möglich, da das Muster für Look Behind keine variable Länge haben darf (auf oberster Ebene sind Alternativen jeweils fester Länge möglich, das hilft hier aber nicht weiter).


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Muster fuer POS(n)
puts "\n>>>>> Muster: /<pos(10)>test/ <<<<<"
strs = ['.........test...',
'..........test...',
'...........test...']
pattern = /(?<=^.{10})test/
puts "Pattern: #{pattern.inspect}"
strs.each do |str|
puts "\nString: '#{str}'"
if (res = str.match(pattern)) then
puts "Match: '#{res}'"
else
puts "+++++ No Match"
end
end
Ergibt

1
2
3
4
5
6
7
8
9
10
11
>>>>> Muster: /<pos(10)>test/ <<<<<
Pattern: /(?<=^.{10})test/

String: '.........test...'
+++++ No Match

String: '..........test...'
Match: 'test'

String: '...........test...'
+++++ No Match

Nun noch zu den Tabulator-Mustern. rtab(n) geht auch wieder unter Ruby 1.8, da Positive Look Ahead benutzt wird.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Muster fuer RTAB(n)
puts "\n>>>>> Muster: /a<rtab(10)>test/) <<<<<"
strs = ['a..test.....',
'a..test......',
'a..test.......']
pattern = /a.*(?=.{10}$)test/
puts "Pattern: #{pattern.inspect}"
strs.each do |str|
puts "\nString: '#{str}'"
if (res = str.match(pattern)) then
puts "Match: '#{res}'"
else
puts "+++++ No Match"
end
end
Ergibt

1
2
3
4
5
6
7
8
9
10
11
>>>>> Muster: /a<rtab(10)>test/) <<<<<
Pattern: /a.*(?=.{10}$)test/

String: 'a..test.....'
+++++ No Match

String: 'a..test......'
Match: 'a..test'

String: 'a..test.......'
+++++ No Match

Das letzte aufzuführende Element, tab(n), benötigt wieder Ruby 1.9, da Positive Look Behind benötigt wird.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Muster fuer TAB(n)
puts "\n>>>>> Muster: /a<tab(10)>test/ <<<<<"
strs = ['a........test...',
'a.........test...',
'a..........test...']
pattern = /a.*(?<=^.{10})test/
puts "Pattern: #{pattern.inspect}"
strs.each do |str|
puts "\nString: '#{str}'"
if (res = str.match(pattern)) then
puts "Match: '#{res}'"
else
puts "+++++ No Match"
end
end
Ergibt

1
2
3
4
5
6
7
8
9
10
11
>>>>> Muster: /a<tab(10)>test/ <<<<<
Pattern: /a.*(?<=^.{10})test/

String: 'a........test...'
+++++ No Match

String: 'a.........test...'
Match: 'a.........test'

String: 'a..........test...'
+++++ No Match

So, jetzt habe ich aber genug von der Tipperei bei der Hitze - vielleicht kann diese Fragmente ja irgendjemand nutzen.

_________________
WoNáDo.set_state!(:retired)


Nach oben
 Profil  
 
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 1 Beitrag ] 

Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 2 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach: