[Regex] Meerdere groepen tussen 2 strings

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Eppo ©
  • Registratie: Juni 2004
  • Niet online
Ik kom er even niet aan uit en volgens mij moet het vrij simpel zijn. Ik wil namelijk de nummers tussen 2 strings uithalen. Het kan zijn dat er 1 nummer staat, maar er kunnen er ook meerdere zijn.

Voorbeeld tekst:
999993111 Example text start 999993112 999993113 999993114 Example text end 999993115

Als ik daar de regex (\d{9}) op gebruik, dan krijg ik 5 resultaten
https://regex101.com/r/4rquZH/1

Maak ik daar (\d{9})(?=.*end) van, dan kan hij alles vinden voor de end
https://regex101.com/r/c18J6m/1

Met start.*(\d{9}) vind hij alleen de laatste na start (999993115)
https://regex101.com/r/ADJCXF/1

Met start.*(\d{9}).*end vind hij alleen 999993114
https://regex101.com/r/si9UUn/1

Hoe krijg ik het voor elkaar dat ik met Regex alleen de nummers 999993112 999993113 999993114 terug krijg? Of is dat niet mogelijk met 1 Regex?

Alle reacties


Acties:
  • 0 Henk 'm!

  • thunder7
  • Registratie: Januari 2003
  • Laatst online: 08:52

thunder7

houten vaas/schaal nodig?

Cijfers teruggeven = letters weghalen, lijkt me? sed -e"s/[A-Za-z]*//g"

hout-nerd - www.hetmooistehout.nl of www.houtenschalen.nl


Acties:
  • 0 Henk 'm!

  • flip77
  • Registratie: Maart 2006
  • Laatst online: 26-09 18:09
En wat als je de eerste en laatste cijfercombinatie wel matched maar niet een group van maakt:

^(?:\d{9})|(?:\d{9})$|(\d{9})

Acties:
  • 0 Henk 'm!

  • Oon
  • Registratie: Juni 2019
  • Niet online

Oon

Als je specifiek <niet nummer> <nummer(s)> <niet nummer> zoekt dan zou je met het volgende uitkomen:

[^\d\s]+([\d\s]+)[^\d\s]+

Je zoekt dan op '1 of meer keer alles behalve cijfers en spaties', '1 of meer keer cijfers of spaties', 'een of meer keer alles behalve cijfers en spaties', waarbij je de middelste als capture group gebruikt.

Acties:
  • 0 Henk 'm!

  • plofkip
  • Registratie: Oktober 2002
  • Laatst online: 29-09 20:13
In dit geval werkt dit ook:
code:
1
[^\d]+? ([\d ]+) [^\d]+?

Vraag is welke voorbeelden er nog meer moeten valideren :-)

Acties:
  • 0 Henk 'm!

  • CyBeRSPiN
  • Registratie: Februari 2001
  • Laatst online: 12:17

CyBeRSPiN

sinds 2001

Zoek op "capturing a repeated group", als je die 3 (of willekeurig aantal) nummers perse als losse match wilt hebben.
https://stackoverflow.com/a/65244969

Maar anders wat @plofkip hierboven zegt. Je kunt dan met een simpele split op spatie alsnog de getallen lostrekken.

Bij nader inzien lijkt dat repeaten van een capture group niet te gaan werken, zie ook de comments in de link.

[ Voor 99% gewijzigd door CyBeRSPiN op 15-08-2022 15:16 ]


Acties:
  • 0 Henk 'm!

  • Eppo ©
  • Registratie: Juni 2004
  • Niet online
thunder7 schreef op maandag 15 augustus 2022 @ 14:48:
Cijfers teruggeven = letters weghalen, lijkt me? sed -e"s/[A-Za-z]*//g"
Nee, ik heb alleen de cijfers nodig die tussen begin en eind staan nodig. Dus als alle letters weghaal, dan krijg ik ook de cijfers mee die voor het begin staan en na het eind
flip77 schreef op maandag 15 augustus 2022 @ 14:51:
En wat als je de eerste en laatste cijfercombinatie wel matched maar niet een group van maakt:

^(?:\d{9})|(?:\d{9})$|(\d{9})
De string is langer dan dit en het is mogelijk dat vaker 9 cijfers voorkomen. Om die reden wil ik dat hij echt alleen tussen begin en eind kijkt
Oon schreef op maandag 15 augustus 2022 @ 14:56:
Als je specifiek <niet nummer> <nummer(s)> <niet nummer> zoekt dan zou je met het volgende uitkomen:

[^\d\s]+([\d\s]+)[^\d\s]+

Je zoekt dan op '1 of meer keer alles behalve cijfers en spaties', '1 of meer keer cijfers of spaties', 'een of meer keer alles behalve cijfers en spaties', waarbij je de middelste als capture group gebruikt.
Dan maakt hij er 1 lange string van. Het is niet mogelijk om het gelijk in groepen terug te krijgen?

Acties:
  • 0 Henk 'm!

  • Oon
  • Registratie: Juni 2019
  • Niet online

Oon

Eppo © schreef op maandag 15 augustus 2022 @ 15:03:
[...]
Nee, ik heb alleen de cijfers nodig die tussen begin en eind staan nodig. Dus als alle letters weghaal, dan krijg ik ook de cijfers mee die voor het begin staan en na het eind


[...]

De string is langer dan dit en het is mogelijk dat vaker 9 cijfers voorkomen. Om die reden wil ik dat hij echt alleen tussen begin en eind kijkt


[...]
Dan maakt hij er 1 lange string van. Het is niet mogelijk om het gelijk in groepen terug te krijgen?
Heb je de mogelijkheid om een tweede capture te doen? Als je eenmaal de ene string hebt kun je deze makkelijk splitsen.

Het zou ook in één regex moeten kunnen als je een subgroep of whole-world match doet

Acties:
  • 0 Henk 'm!

  • nescafe
  • Registratie: Januari 2001
  • Laatst online: 10:03
Example text start (\d+\s?)* Example text end

Evt. om separate woorden af te dwingen:

Example text start (\b\d+\b\s?)* Example text end

[ Voor 48% gewijzigd door nescafe op 15-08-2022 15:22 ]

* Barca zweert ook bij fixedsys... althans bij mIRC de rest is comic sans


Acties:
  • 0 Henk 'm!

  • Eppo ©
  • Registratie: Juni 2004
  • Niet online
@Oon Ja, heb het nu gewoon met 2 regexen opgelost. Het leek mij dubbel en dat het mogelijk simpeler kon, maar op deze manier werkt het en snap ik het ook nog

@nescafe Die optie had ik ook, maar dan krijg ik geen groepen terug
Met start.*(\d{9}).*end vind hij alleen 999993114
https://regex101.com/r/si9UUn/1

Acties:
  • 0 Henk 'm!

  • erwn
  • Registratie: November 2020
  • Niet online
Ik denk dat het voor de onderhoudbaarheid sowieso handiger is om dit in twee stappen te doen. Het kan in ieder geval niet met één eenvoudige expressie. Begrijp je over een half jaar die code dan nog?

En misschien is het ook gewoon sneller om het in twee stappen te doen. Een tweede expressie of splitten op spatie kost weinig tijd.

Uit nieuwsgierigheid heb ik het nog wel (zonder resultaat) geprobeerd; ik vroeg me af of je iets zou kunnen met lookarounds.

Acties:
  • 0 Henk 'm!

  • BernardV
  • Registratie: December 2003
  • Laatst online: 10:00
Eppo © schreef op maandag 15 augustus 2022 @ 15:31:
@Oon Ja, heb het nu gewoon met 2 regexen opgelost. Het leek mij dubbel en dat het mogelijk simpeler kon, maar op deze manier werkt het en snap ik het ook nog
Zoiets bedoel je?
code:
1
(?<=\s)(\d+)(?=\s)


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

Acties:
  • 0 Henk 'm!

  • Oon
  • Registratie: Juni 2019
  • Niet online

Oon

Ja, alleen zouden die lookbehind en lookahead ook op \w moeten checken ipv alleen \s, want het gaat specifiek om reeksen van cijfers tussen reeksen van niet-cijfers. Als je nu aan het einde een spatie toevoegt dan matcht hij die ook

Acties:
  • +1 Henk 'm!

  • BernardV
  • Registratie: December 2003
  • Laatst online: 10:00
Oon schreef op maandag 15 augustus 2022 @ 16:28:
[...]

Ja, alleen zouden die lookbehind en lookahead ook op \w moeten checken ipv alleen \s, want het gaat specifiek om reeksen van cijfers tussen reeksen van niet-cijfers. Als je nu aan het einde een spatie toevoegt dan matcht hij die ook
Ah ja, dat is ook redelijk makkelijk opgelost:

code:
1
(?<=[^^]\s)(\d+)(?=\s[^$])


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

Maar als dit echt voor kan komen is het makkelijker om een 'trim' om de input te zetten voordat je de regex er op loslaat.
Pagina: 1