Jump to content

Split string at n'th space in n'th length


Rex
 Share

Recommended Posts

Hi

As usual I have problems with the math :'(

I have a text there's xx long, I need to split it into strings there is 74 Chars long, but to make the text readable I want to split at the last space near the 74. limit.

eg.

A child asked his father, "How were people born?" So his father said, "Adam and Eve made babies, then their babies became adults and made babies, and so on." The child then went to his mother, asked her the same question and she told him, "We were monkeys then we evolved to become like we are now." The child ran back to his father and said, "You lied to me!" His father replied, "No, your mom was talking about her side of the family."

Should look something like this:

A child asked his father, "How were people born?" So his father said, "Adam and Eve made babies,
then their babies became adults and made babies, and so on." The child then went to his mother,
asked her the same question and she told him, "We were monkeys then we evolved to become like
we are now." The child ran back to his father and said, "You lied to me!" His father replied, "No,
your mom was talking about her side of the family."

When spitted.

My first approach was to use stringsplit at every space, and the count the length of every array +1 , until I was close to 74.
But then I realized that It would be like walking across the river to get an empty bucket, an then return to fill it with water :/

So then I thought about stringtrimleft at 74, and then do a stringinstr to find the last  space, and then do another string trim on the original string using the result from the stringinstr, but I couldn't get it to work, and after trying for 2 hours I deleted the code - and went for a long walk with the dog, before I did something stupid like inviting the pc to a boxing game or some thing like that.

Could some one help me by pointing me in the right direction on how to do this :)

 

Cheers
/Rex

Edited by Rex
Link to comment
Share on other sites

  • Moderators

Rex,

A fun little challenge for a Friday afternoon:

#include <String.au3>

$sString = 'A child asked his father, "How were people born?" So his father said, "Adam and Eve made babies, then their babies became adults and made babies, and so on." The child then went to his mother, asked her the same question and she told him, "We were monkeys then we evolved to become like we are now." The child ran back to his father and said, "You lied to me!" His father replied, "No, your mom was talking about her side of the family."'
$sNewString = ""

$iLineStart = 1     ; Position of character at which line starts
$iLastSpace = 0     ; Position of last space found
$iCount = 0         ; Position of character to check
$iMaxLine = 74      ; Max line length

ConsoleWrite(_StringRepeat("-", $iMaxLine) & "|" & @CRLF) ; Just for display

While 1
    ; Move to next character
    $iCount += 1
    ; If at end of string
    If $iLineStart + $iCount > StringLen($sString) Then
        ; Write line
        $sNewString &= StringMid($sString, $iLineStart)
        ; Exit loop
        ExitLoop

    EndIf

    ; Set position of character if space
    If StringMid($sString, $iLineStart + $iCount, 1) = " " Then
        $iLastSpace = $iLineStart + $iCount

    EndIf

    ; If at line end
    If $iCount = $iMaxLine Then
        ; Write line up to last space
        $sNewString &= StringMid($sString, $iLineStart, $iLastSpace - $iLineStart) & @CRLF
        ; reset for next line
        $iLineStart = $iLastSpace + 1
        $iCount = 0
    EndIf

WEnd



ConsoleWrite($sNewString & @CRLF)

Please ask if you have any questions.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

@kylomas
Thx that looks swell, never thought that it could be done with regexp.

@Melba23

A little challenge, I was so close to break my keyboard in half, after trying for 2 hours to accomplice what you did, in what 2 min :o
One Q.

I tried to to ad every line into an array, but of course me and arrays don't work well together either :censored:, so I just did a StringSplit($sNewString, @crlf) but ended up with "line | blank line | line | blank line" anso.

What am I doing wrong?

First i tried to make your script add the lines to an array by adding the line $aNewString[$i] = StringMid($sString, $iLineStart, $iLastSpace - $iLineStart) but SciTE told me that she hate me, and that I should find some thing else to do with my life, or some thing like that :D

 

Cheers

/Rex

Edited by Rex
Link to comment
Share on other sites

  • Moderators

Rex,

If you split on @CRLF you must remember it is 2 characters (as explained in the Help file) so you will need to use:

$aLines = StringSplit($sNewString, @CRLF, $STR_ENTIRESPLIT + $STR_NOCOUNT)

Adding the lines to an array as you go along is not too difficult:

#include <Array.au3>

$sString = 'A child asked his father, "How were people born?" So his father said, "Adam and Eve made babies, then their babies became adults and made babies, and so on." The child then went to his mother, asked her the same question and she told him, "We were monkeys then we evolved to become like we are now." The child ran back to his father and said, "You lied to me!" His father replied, "No, your mom was talking about her side of the family."'
$sNewString = ""

$iLineStart = 1     ; Position of character at which line starts
$iLastSpace = 0     ; Position of last space found
$iCount = 0         ; Position of character to check
$iMaxLine = 74      ; Max line length

; Get a approximate line count and create array - the code will expand it if necessary
$iTotalLines = Int(StringLen($sString) / $iMaxLine)
Global $aLines[$iTotalLines]

While 1
    ; Move to next character
    $iCount += 1
    ; If at end of string
    If $iLineStart + $iCount > StringLen($sString) Then
        ; Add line to array
        $iTotalLines = _AddLine(StringMid($sString, $iLineStart))
        ; Exit loop
        ExitLoop

    EndIf



    ; Set position of character if space
    If StringMid($sString, $iLineStart + $iCount, 1) = " " Then
        $iLastSpace = $iLineStart + $iCount

    EndIf



    ; If at line end
    If $iCount = $iMaxLine Then
        ; Write line up to last space to array
        $iTotalLines = _AddLine(StringMid($sString, $iLineStart, $iLastSpace - $iLineStart))
        ; Reset for next line
        $iLineStart = $iLastSpace + 1
        $iCount = 0
    EndIf



WEnd



; Remove any blank lines
ReDim $aLines[$iTotalLines]
_ArrayDisplay($aLines, "", Default, 8)

Func _AddLine($sLine)
    
    ; Index of the next line to write to in the array
    Local Static $iNextLine = 0
    ; Write to that line
    $aLines[$iNextLine] = $sLine

    ; Next line index
    $iNextLine += 1
    ; Resize the array if it is now too small
    If $iNextLine > UBound($aLines) - 1 Then
        ; Double it in size
        ReDim $aLines[UBound($aLines) * 2]
    EndIf

    ; Return the last line written
    Return $iNextLine



EndFunc

That should be easy enough to follow.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

#include<array.au3>

$str = 'A child asked his father, "How were people born?" So his father said, "Adam and Eve made babies, then their babies became adults and made babies, and so on." The child then went to his mother, asked her the same question and she told him, "We were monkeys then we evolved to become like we are now." The child ran back to his father and said, "You lied to me!" His father replied, "No, your mom was talking about her side of the family."'

$aWords = stringsplit($str , " " , 2)

$sOut = ""
$sRtn = ""

for $i = 0 to ubound($aWords) - 2
    $sOut &= $aWords[$i] & " "
    If stringlen($sOut) + stringlen($aWords[$i + 1]) >= 74 Then
        $sRtn &= $sOut & @CRLF
        $sOut = ""
    EndIf
next

$sRtn = $sRtn & $aWords[ubound($aWords) - 1]

msgbox(0, '' , $sRtn)

 

Can probably be cleaned to slap the last word into the last line if under 74 chars, but if you are only going for legibility...

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

  • Moderators

iamtheky,

Nice.

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

@iamtheky

Wow that looks like my first thinking, that I threw away thinking it would be overkill to split it all and then count each one, but then again my code would be at least double as long as yours, and probably still not be working :$

You all got my deepest respect for your knowledge :ILA2:

Cheers
/Rex

Link to comment
Share on other sites

Hmmm this does the job too ;)

Local $sString =  'A child asked his father, "How were people born?" So his father said, "Adam and Eve made babies, then their babies became adults and made babies, and so on." The child then went to his mother, asked her the same question and she told him, "We were monkeys then we evolved to become like we are now." The child ran back to his father and said, "You lied to me!" His father replied, "No, your mom was talking about her side of the family."'

$x = 74
$res = StringRegExpReplace($sString, ".{1," & $x - 1 & "}\K(\s{1,2}|$)", @CRLF)

Msgbox(0,"", $res)

 

Link to comment
Share on other sites

  • Moderators

mikell,

OK you win. Now explain the RegEx in detail, because that is way over my head!

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Melba,
It's not matter of "winning" (iamtheky's solution is very clever) it's matter of alternatives :)

StringRegExpReplace($str, ".{1,74}\K(\s{1,2}|$)", @crlf)
It counts 1 to 74 characters (any except newline) until 1 or 2 spaces (or end of string), and replace these spaces by @crlf
This allows to catch the space the nearest from count 74
As the regex continues after the match, the \K (meaning "forget what you have seen before") makes the search go on from this point - until it fails after end of string

Hum not sure I was clear enough... :sweating:

 

Link to comment
Share on other sites

  • Moderators

mikell,

It's not matter of "winning"

I know - it was a figure of speech. 

not sure I was clear enough

Not at all - it forced me to look at "/K", which I had never used before, and which I shall examine with renewed interest. Merci beaucoup.

M23

Edited by Melba23
Typo - I need that new keyboard!

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

mikell,

When run with this SRE

$res = StringRegExpReplace($sString, ".{1," & $x - 1 & "}(\s{1,2}|$)", @CRLF)

it does 7 replacements but returns a blank string.  Can you explain in more detail the affect of the \K?

kylomas

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

will it always replace the current collection AND continue where it left off (or are there many edge cases that would blow this one up)?   Is there an easier string to send through it to show what it is actually doing?

It is a confusing SRE for me as well as the rest of the class :)

Edited by iamtheky

,-. .--. ________ .-. .-. ,---. ,-. .-. .-. .-.
|(| / /\ \ |\ /| |__ __||| | | || .-' | |/ / \ \_/ )/
(_) / /__\ \ |(\ / | )| | | `-' | | `-. | | / __ \ (_)
| | | __ | (_)\/ | (_) | | .-. | | .-' | | \ |__| ) (
| | | | |)| | \ / | | | | | |)| | `--. | |) \ | |
`-' |_| (_) | |\/| | `-' /( (_)/( __.' |((_)-' /(_|
'-' '-' (__) (__) (_) (__)

Link to comment
Share on other sites

ditto to iamthekey...despite jchd's best attempts he could not reach low enough for me to understand the practicality of

Resets start of match at the current point in subject string. Note that groups already captured are left alone and still populate the returned array; it is therefore always possible to backreference to them later on. Action of \K is similar but not identical to a look-behind, in that \K can work on alternations of varying lengths.

kylomas 

Forum Rules         Procedure for posting code

"I like pigs.  Dogs look up to us.  Cats look down on us.  Pigs treat us as equals."

- Sir Winston Churchill

Link to comment
Share on other sites

  • Moderators

Advance apologies for the blood dripping from my brain,

I read the SRER like this:

.{1, 73}  ; Up to 73 characters
\K        ; (and if a match is found start counting again from the point the match stops)
(         ; then replace either
\s{1,2}   ; 1 or 2 spaces
|         ; or
$         ; the end of the string
)         ; by @CRLF

But I could be wrong....,,

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • Moderators

kylomas,

My best guess?

Because if there is no "\K" then the whole match (characters and spaces) gets replaced and so there is nothing but a series of @CRLF. With the reset the characters are left in place and only the spaces are replaced.

But quite why this happens I cannot explain as the only capturing group appears to be the spaces. Like I have said many times, RegExs make my brain bleed....

M23

Edited by Melba23
Added final comment!

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...