String Range forward and backward lookaround

2020-07-27 05:30发布

问题:

I am trying to write a script that gets input from a user and returns the input in a formatted area. I have been using the string range function however it obviously cuts the the input at the range that I give. Is there any way to do a look around at the specified range to find the next space character and cut the input at that location?

For example, if I have the input of:

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris

My current string range function formats the input with \r\n as such:

Lorem ipsum dolor sit amet, consectetur a
dipisicing elit, sed do eiusmod tempor in
cididunt ut labore et dolore magna aliqua
. Ut enim ad minim veniam, quis nostrud e
xercitation ullamco laboris

As you can see on line 1 the adipisicing line 2 incididunt words have been cut off. I am looking for a way to look for the closest space to that location. So for line 1 it would have been before the a on line 2 it would have been before the i. …In some cases it may be after the word.

Is that clear what I am looking for? Any assistance would be great!

回答1:

The string range operation is pretty stupid; it doesn't know anything about the string it is splitting other than that it contains characters. To get smarter splitting, your best bet is probably an intelligently chosen regular expression:

set s "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\
nostrud exercitation ullamco laboris."

# Up to 40 characters, from word-start, to word-start or end-of-string
set RE {\m.{1,40}(?:\m|\Z)}
# Extract the split-up list of "lines" and print them as lines
puts [join [regexp -all -inline $RE $s] "\n"]

This produces this output for me:

Lorem ipsum dolor sit amet, consectetur 
adipisicing elit, sed do eiusmod tempor 
incididunt ut labore et dolore magna 
aliqua. Ut enim ad minim veniam, quis 
nostrud exercitation ullamco laboris.

Implementing full justification by inserting spaces is left as an exercise for the reader (because it's really quite a lot harder than greedy line splitting!)



回答2:

The textutil::adjust module in tcllib is what you need:

package require textutil::adjust
set line "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris"
set formatted [textutil::adjust::adjust $line -length 41]
puts $formatted
Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris