Applications, Games, Tools, User libs and useful stuff coded in PureBasic
AZJIO
Addict
Posts: 2141 Joined: Sun May 14, 2017 1:48 am
Post
by AZJIO » Sun Jul 17, 2022 7:12 pm
bgeraghty wrote: Sun Jul 17, 2022 3:59 pm
I like the idea of using StringField() for this, didn't think of that.
StringField() - not economical.
BarryG wrote: Sun Jul 17, 2022 1:51 am
Code: Select all
l=FindString(text$,left$)
r=FindString(text$,right$,l+1)
If the first lookup fails, then the second lookup is not necessary.
BarryG
Addict
Posts: 4118 Joined: Thu Apr 18, 2019 8:17 am
Post
by BarryG » Sun Jul 17, 2022 10:00 pm
I'm surprised that there wasn't a RegEx example in this topic.
Little John
Addict
Posts: 4770 Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany
Post
by Little John » Sun Jul 17, 2022 11:14 pm
BarryG wrote: Sun Jul 17, 2022 10:00 pm
I'm surprised that there wasn't a RegEx example in this topic.
Here you go!
Code: Select all
; PB 6.00 LTS
EnableExplicit
Procedure.i StringBetween (source$, before$, after$, Array found$(1))
; keywords for getting more information: positive lookbehind, positive lookahead, metacharacters, repetition, laziness
Protected.i regEx, nFound
regEx = CreateRegularExpression(#PB_Any, "(?<="+before$+").*?(?="+after$+")", #PB_RegularExpression_DotAll|#PB_RegularExpression_NoCase)
nFound = ExtractRegularExpression(regEx, source$, found$())
FreeRegularExpression(regEx)
ProcedureReturn nFound
EndProcedure
Define source$, before$, after$, n.i, i.i
Dim found$(0)
source$ = "<b>1st bold</b> expression, <b>2nd bold</b> expression, <b>3rd bold</b> expression"
before$ = "<b>" : after$ = "</b>"
n = StringBetween(source$, before$, after$, found$())
For i = 0 To n-1
Debug "'" + found$(i) + "'"
Next
AZJIO
Addict
Posts: 2141 Joined: Sun May 14, 2017 1:48 am
Post
by AZJIO » Mon Jul 18, 2022 3:28 am
BarryG wrote: Sun Jul 17, 2022 10:00 pm
I'm surprised that there wasn't a RegEx example in this topic.
Increases the file size by 150-200 kb
BarryG
Addict
Posts: 4118 Joined: Thu Apr 18, 2019 8:17 am
Post
by BarryG » Mon Jul 18, 2022 9:02 am
AZJIO wrote: Sun Jul 17, 2022 7:12 pm If the first lookup fails, then the second lookup is not necessary.
True! That was very old code that I wrote that I hadn't revisited for years (until this topic). I've amended it based on your comment:
Code: Select all
Procedure.s PluckString(text$,left$,right$)
l=FindString(text$,left$)
If l
r=FindString(text$,right$,l+1)
If r
p$=Mid(Left(text$,r-1),l+Len(left$))
EndIf
EndIf
ProcedureReturn p$
EndProcedure
But I have a question: How can I make the following code return just "1", if the text before and after it changes?
Code: Select all
Procedure.s PluckString(text$,left$,right$)
l=FindString(text$,left$)
If l
r=FindString(text$,right$,l+1)
If r
p$=Mid(Left(text$,r-1),l+Len(left$))
EndIf
EndIf
ProcedureReturn p$
EndProcedure
random$=Str(Random(999,100)) ; Will be "100" to "999".
string$="<italic>Value</italic><"+random$+">1 AUD</"+random$+">"
Debug PluckString(string$, ">", " AUD") ; Want just "1" returned.
ar-s
Enthusiast
Posts: 344 Joined: Sat Oct 06, 2007 11:20 pm
Location: France
Post
by ar-s » Mon Jul 18, 2022 10:38 am
My contribution when there are several occurrences.
Code: Select all
Declare.b StringBetween(String$, StartString$, EndString$)
Global NewList Strings.s()
Procedure.b StringBetween(String$, StartString$, EndString$)
Protected N = 0, S1=0, E1=0, P1=0, P2=0
ClearList(Strings())
S1 = CountString(String$, StartString$)
E1 = CountString(String$, EndString$)
If S1 > 0 And E1 >0
N+1
EndIf
If N = 0
ProcedureReturn 0
ElseIf S1 > E1
N = S1
Else
N = E1
EndIf
POS = 0
For i = 0 To N-1
P1 = FindString(string$, StartString$, POS) : P2 = FindString(string$, EndString$, POS)
res$ = Mid(string$,P1+Len(StartString$),P2-(P1+Len(StartString$)))
If Len(res$)>0
AddElement( Strings() )
Strings() = res$
EndIf
POS = p2+Len(EndString$)
Next
ProcedureReturn 1
EndProcedure
; ======= Example =========
T$ = "<title>Find me : title</title> Hello world <title>Catch me</title>"
If StringBetween(T$, "<title>", "</title>")
ForEach Strings()
Debug Strings()
Next
Else
Debug "no result"
EndIf
mk-soft
Always Here
Posts: 6201 Joined: Fri May 12, 2006 6:51 pm
Location: Germany
Post
by mk-soft » Mon Jul 18, 2022 4:54 pm
Code: Select all
;-TOP by mk-soft
Procedure StringBetweenList(String.s, Left.s, Right.s, List Result.s())
Protected pos1, pos2, len1, len2
ClearList(Result())
len1 = Len(Left)
len2 = Len(Right)
Repeat
pos1 = FindString(String, Left, pos1)
If pos1
pos1 + len1
pos2 = FindString(String, Right, pos1)
If pos2
AddElement(Result())
Result() = Mid(String, pos1, pos2 - pos1)
pos1 = pos2 + len2
Else
Break
EndIf
Else
Break
EndIf
ForEver
ProcedureReturn ListSize(Result())
EndProcedure
; ======= Example =========
Define NewList r1.s()
text.s = "<title>Find me : title</title><title>Hello world!</title> DATA 123456789 <title>Catch me</title><title>Error missing end"
Define cnt = StringBetweenList(text, "<title>", "</title>", r1())
Debug "Count = " + cnt
ForEach r1()
Debug r1()
Next
davido
Addict
Posts: 1890 Joined: Fri Nov 09, 2012 11:04 pm
Location: Uttoxeter, UK
Post
by davido » Mon Jul 18, 2022 6:42 pm
@mk-soft ,
Excellent. Very useful.
Thank you for sharing.
DE AA EB
Allen
Enthusiast
Posts: 103 Joined: Wed Nov 10, 2021 2:05 am
Post
by Allen » Thu Aug 25, 2022 3:30 pm
Hi,
BarryG wrote: Mon Jul 18, 2022 9:02 am
AZJIO wrote: Sun Jul 17, 2022 7:12 pm If the first lookup fails, then the second lookup is not necessary.
True! That was very old code that I wrote that I hadn't revisited for years (until this topic). I've amended it based on your comment:
Code: Select all
Procedure.s PluckString(text$,left$,right$)
l=FindString(text$,left$)
If l
r=FindString(text$,right$,l+1)
If r
p$=Mid(Left(text$,r-1),l+Len(left$))
EndIf
EndIf
ProcedureReturn p$
EndProcedure
But I have a question: How can I make the following code return just "1", if the text before and after it changes?
Code: Select all
Procedure.s PluckString(text$,left$,right$)
l=FindString(text$,left$)
If l
r=FindString(text$,right$,l+1)
If r
p$=Mid(Left(text$,r-1),l+Len(left$))
EndIf
EndIf
ProcedureReturn p$
EndProcedure
random$=Str(Random(999,100)) ; Will be "100" to "999".
string$="<italic>Value</italic><"+random$+">1 AUD</"+random$+">"
Debug PluckString(string$, ">", " AUD") ; Want just "1" returned.
My attempt to solve this question.
Code: Select all
EnableExplicit
Procedure.s PluckString(String$,Start$,End$)
Protected.i StartPos,EndPos,Tmp
Protected.s Tmp$
EndPos=FindString(String$,End$)
If EndPos
Tmp$=Left(String$,EndPos-1)
StartPos=0
Repeat
Tmp=FindString(Tmp$,Start$,StartPos)
If Tmp=0
ProcedureReturn Mid(Tmp$,StartPos)
Else
StartPos=Tmp+1
EndIf
ForEver
EndIf
ProcedureReturn ""
EndProcedure
Define.s random$,string$
random$=Str(Random(999,100)) ; Will be "100" to "999".
string$="<italic>Value</italic><"+random$+">1 AUD</"+random$+">"
Debug PluckString(string$, ">", " AUD") ; Want just "1" returned.
Allen