Sign in to follow this  
Followers 0
Ármányos Kő

Express numbers from string

12 posts in this topic

Hi,

I wanted to make a Func which expresses the number elements from a string. This is what I have come up with, but I am not sure if some other method could be used.

This is essentially based on checking every single character in the string which can take time if string is long.

Any tricky different solution to this, not based on actually reading through the text by characters?

Func string_collect_nums($string)                                                   ; no error checking is included
    $l = StringLen($string)
    $foundnum_locs = ""
    $num_length = 0
    $step = 0
    For $i = 1 To $l
        $check = StringMid($string, $i, 1)
        If Asc($check) > 47 And Asc($check) < 58 Then                               ; if number found
            $step = 1                                                               ; we count the numbers
            $num_length = 1
            $do_exit = False
            Do 
                If $i+$step < $l+1 Then 
                    $check_num = StringMid($string, $i+$step, 1)
                    If Asc($check_num) > 47 And Asc($check_num) < 58 Then           
                        $num_length = $num_length + 1
                        $step = $step + 1
                    Else
                        $do_exit = True                                             ; exit if end of number
                    EndIf
                Else
                    $do_exit = True                                                 ; exit if end of string
                EndIf
            Until $do_exit = True
            $foundnum_locs = $foundnum_locs&$i&"="&StringMid($string, $i, $num_length)&"¦"         ;adjust format to your needs...
            If $i+$num_length < $l+1 Then 
                $i = $i+$num_length
                $num_length = 0
                $i = $i - 1
            EndIf
        EndIf
    Next
    If $foundnum_locs <> "" Then
        MsgBox( 0,"string_collect_nums",$string&@CRLF&$foundnum_locs)       ; here you get the results...  Do some stringsplits to get the result seperated
    EndIf
    Return $foundnum_locs
EndFunc

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Hi,

I wanted to make a Func which expresses the number elements from a string.

Do it the oposite way: Eliminate all non-numeric CHARs

$MyString="9Foo1234Bar6543Dummy2345"

$NumString=StringRegExpReplace($MyString,"\D+","")
MsgBox(0,"Numbers in Sring",$NumString & @LF & @error)

"\D" is any non-numeric element

"+" is one or more occurences (so if there are blocks of non numeric, they will be replaced with "" in one step)

Have a look to the autoit docs, search for "RegEx"

Regards, Rudi.

Edited by rudi

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

Share this post


Link to post
Share on other sites

Do it the oposite way: Eliminate all non-numeric CHARs

$MyString="9Foo1234Bar6543Dummy2345"

$NumString=StringRegExpReplace($MyString,"\D+","")
MsgBox(0,"Numbers in Sring",$NumString & @LF & @error)

"\D" is any non-numeric element

"+" is one or more occurences (so if there are blocks of non numeric, they will be replaced with "" in one step)

Have a look to the autoit docs, search for "RegEx"

Regards, Rudi.

This sounds great, only that I need to know where the numbers were in the original string (by character location) and I need to know the numbers as numbers like 9 AND 1234 AND 6543 AND 2345.

But I'll have a look on StringRegExpReplace. I have not thought of using it yet.

Share this post


Link to post
Share on other sites

If you need to know the original index's of the digits I don't think StringRegExp() will do much good. You will instead have to use StringSplit().

$myString="9Foo1234Bar6543Dummy2345"

$myArray = StringSplit($myString, "")

For $X = 1 to $myArray[0]

If NOT IsNumber ($myArray[$X]) Then $myArray[$X] = ""

Next

Unfortunately this way will not group the numbers together. Maybe we need more info since wanting the numbers seperated but neededing their starting position seems odd.

Share this post


Link to post
Share on other sites

If you need to know the original index's of the digits I don't think StringRegExp() will do much good. You will instead have to use StringSplit().

$myString="9Foo1234Bar6543Dummy2345"

$myArray = StringSplit($myString, "")

For $X = 1 to $myArray[0]

If NOT IsNumber ($myArray[$X]) Then $myArray[$X] = ""

Next

Unfortunately this way will not group the numbers together. Maybe we need more info since wanting the numbers seperated but neededing their starting position seems odd.

I am on translation automation.

I want to find numbers in the original text and insert them to the translated text coming from a database. Database gives good translated sentences from earlier translations (bi-lingual corpus), however sometimes the numbers do not match only. I want then to insert the known numbers from the original sentence. This is why I need to know their original location in the sentence.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

If I understand what you want, your func is buggy.

Test $string = '9 AND 1234 AND 6543 AND 2345'

Produces output: '1=9¦7=1234¦16=6543¦25=2345¦26=345¦27=45¦28=5¦'

One of the ways to do it...

Func string_collect_nums2($string)
    Local $sRet = "", $aParse, $iEl, $iPos = 0
    $aParse = StringRegExp($string, '\d+', 3)
    If Not @error Then
        For $iEl = UBound($aParse)-1 To 0 Step -1
            $iPos = StringInStr($string, $aParse[$iEl], 2, -1)
            $sRet = $iPos & "=" & $aParse[$iEl] & "|" & $sRet
            $string = StringLeft($string, $iPos-1)
        Next
    EndIf
    Return $sRet
EndFunc
Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

@OP, your function doesn't post the same output for all instances... I'm assuming after seeing the tail of your function, using weaponx example string, that this is what you wanted... If' it's not, then replace

$sHold &= $nAdd & "=" & StringMid($aSRE[$iCC], $nCC) & "¦"oÝ÷ Ùh­«­¢+ØÀÌØíÍ!½±µÀìôÀÌØí¹µÀìÅÕ½ÐìôÅÕ½ÐìµÀìÀÌØíMIlÀÌØí¹

tµÀìÅÕ½ÐîÅÕ½ÐìoÝ÷ Ù«­¢+ØÀÌØíÍMÑÉ¥¹ôÅÕ½Ðìå½¼ÄÈÌÑ   ÈØÔÐÍÕµµäÈÌÐÔÅÕ½Ðì(ÀÌØíÍ=ÕÐô}µåMÑÉ¥¹Õ¹ ÀÌØíÍMÑÉ¥¹¤)5Í  ½à À°À°ÀÌØíÍ=ÕФ()Õ¹}µåMÑÉ¥¹Õ¹ ÀÌØíÍMÑÉ¥¹¤(%1½°ÀÌØíMIôMÑÉ¥¹IáÀ ÀÌØíÍMÑÉ¥¹°ÅÕ½Ðì ÀäÈí­ðÀäÈí¬¤ÅÕ½Ðì°Ì¤(%1½°ÀÌØí¹°ÀÌØí¹¥¥Ð°ÀÌØí¹MÑÉ¥¹°ÀÌØíÍ!½±°ÀÌØíMÁ±¥Ð(%1½°ÀÌØí¥
°ÀÌØí¹
°ÀÌØí¹U   MIôU   ½Õ¹ ÀÌØíMI¤(%½ÈÀÌØí¥
ôÀQ¼ÀÌØí¹U  MI´Ä($$ÀÌØíMÁ±¥ÐôMÑÉ¥¹MÁ±¥Ð ÀÌØíMIlÀÌØí¥

t°ÅÕ½ÐìÅÕ½Ðì¤($%%%¹Ð ÀÌØíMIlÀÌØí¥

t¤Q¡¸($$%½ÈÀÌØí¹
ôÄQ¼ÀÌØíMÁ±¥ÑlÁt($$$$ÀÌØí¹¬ôÄ($$$$ÀÌØíÍ!½±µÀìôÀÌØí¹µÀìÅÕ½ÐìôÅÕ½ÐìµÀìMÑÉ¥¹5¥ ÀÌØíMIlÀÌØí¥

t°ÀÌØí¹
¤µÀìÅÕ½ÐîÅÕ½Ðì($$%9áÐ($%±Í($$$ÀÌØí¹¬ôÀÌØíMÁ±¥ÑlÁt($%¹%(%9áÐ(%IÑÕɸMÑÉ¥¹QÉ¥µI¥¡Ð ÀÌØíÍ!½±°Ä¤)¹Õ¹

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

I am on translation automation.

I want to find numbers in the original text and insert them to the translated text coming from a database. Database gives good translated sentences from earlier translations (bi-lingual corpus), however sometimes the numbers do not match only. I want then to insert the known numbers from the original sentence. This is why I need to know their original location in the sentence.

After reading this, this may be all that you are after:
$sOut = _myStringFunc($sString)
MsgBox(0, 0, $sOut)

Func _myStringFunc($sString)
    Local $aSRE = StringRegExp($sString, "(\d+|\D+)", 3)
    Local $nAdd, $sHold, $aSplit, $iCC, $nUBSRE = UBound($aSRE)
    For $iCC = 0 To $nUBSRE - 1
        $aSplit = StringSplit($aSRE[$iCC], "")
        If Int($aSRE[$iCC]) Then
            $nAdd += 1
            $sHold &= $nAdd & "=" & $aSRE[$iCC] & "¦"
            $nAdd += ($aSplit[0] - 1)
        Else
            $nAdd += $aSplit[0]
        EndIf
    Next
    Return StringTrimRight($sHold, 1)
EndFunc

Edit3:

Came back to see if anyone had commented... and noticed I had a compare variable in the MsgBox function that wasn't declared (I was comparing the OP posted function with my own).

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

After reading this, this may be all that you are after:

$sOut = _myStringFunc($sString)
MsgBox(0, 0, $sOut)

Func _myStringFunc($sString)
    Local $aSRE = StringRegExp($sString, "(\d+|\D+)", 3)
    Local $nAdd, $sHold, $aSplit, $iCC, $nUBSRE = UBound($aSRE)
    For $iCC = 0 To $nUBSRE - 1
        $aSplit = StringSplit($aSRE[$iCC], "")
        If Int($aSRE[$iCC]) Then
            $nAdd += 1
            $sHold &= $nAdd & "=" & $aSRE[$iCC] & "¦"
            $nAdd += ($aSplit[0] - 1)
        Else
            $nAdd += $aSplit[0]
        EndIf
    Next
    Return StringTrimRight($sHold, 1)
EndFunc

Edit3:

Came back to see if anyone had commented... and noticed I had a compare variable in the MsgBox function that wasn't declared (I was comparing the OP posted function with my own).

SmOke_N!

Thanks, yours seemed OK, but produced this:

1=9¦5=1234¦6=234¦7=34¦8=4¦12=6543¦13=543¦14=43¦15=3¦21=2345¦22=345¦23=45¦24=5

If I change the lines as you suggested, it gives this:

1=Foo¦5=Foo¦6=1234¦7=Bar¦8=6543¦12=Foo¦13=1234¦14=Bar¦15=6543¦21=Foo¦22=1234¦23=Bar¦24=6543

The one in Edit2 gives correct output.

Thanks, StringRegExp will be a help for my next challanges, I think. Powerful stuff.

Share this post


Link to post
Share on other sites

If I understand what you want, your func is buggy.

Test $string = '9 AND 1234 AND 6543 AND 2345'

Produces output: '1=9¦7=1234¦16=6543¦25=2345¦26=345¦27=45¦28=5¦'

One of the ways to do it...

Func string_collect_nums2($string)
    Local $sRet = "", $aParse, $iEl, $iPos = 0
    $aParse = StringRegExp($string, '\d+', 3)
    If Not @error Then
        For $iEl = UBound($aParse)-1 To 0 Step -1
            $iPos = StringInStr($string, $aParse[$iEl], 2, -1)
            $sRet = $iPos & "=" & $aParse[$iEl] & "|" & $sRet
            $string = StringLeft($string, $iPos-1)
        Next
    EndIf
    Return $sRet
EndFunc

Man, this is so clean and short, thanks! I'll stick to this...

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

SmOke_N!

Thanks, yours seemed OK, but produced this:

1=9¦5=1234¦6=234¦7=34¦8=4¦12=6543¦13=543¦14=43¦15=3¦21=2345¦22=345¦23=45¦24=5

If I change the lines as you suggested, it gives this:

1=Foo¦5=Foo¦6=1234¦7=Bar¦8=6543¦12=Foo¦13=1234¦14=Bar¦15=6543¦21=Foo¦22=1234¦23=Bar¦24=6543

Your's gave a messed up result as well, which is what I molded mine after.

The one in Edit2 gives correct output.

Thought it might.

Thanks, StringRegExp will be a help for my next challanges, I think. Powerful stuff.

Yes, I usually use it more than any of the other string functions.

Edit:

Grammar

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Your's gave a messed up result as well, which is what I molded mine after.

Ahh, OK!

Yes, I usually use it more than any of the other string functions.

Maybe I will have to use it more often too. Now I am trying to strip out parts from the original (English) sentences this way>

" (page ", " (pages ", " (p.", " (.page ", ... the beginning is easy, but trying to find the ending block after page numbers part makes me mad. (Something like> " (pages 65, 79, 48)." or " (.page 65, 48) blaa blaah blaa" .......

I keep on trying and when all my ideas failed I'll try to come back with my script.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0