String text manipulation

Is there a way to manipulate string texts? I particular I am trying to strip a layer name from its parent layer name, i.e. convert “parent::child” into “child”. I know how to generate “parent”, but not how to strip it off the total string.

Max.

Something like this?

layer_name='Parent::Child'
parts=layer_name.split('::')
print parts[-1]
>>>'Child'
1 Like

Thank you Mitch! Can you tell me where such syntax info is to be found? I have searched the RhinoPython site and looked into the RhinoPythonPrimer document, but could not find it anywhere. I have little background in programming, I have manipulated strings in MS Excel (Concatenate, Midstr, Leftstr etc.), but that is about all.

Max.

These are basic Python string manipulation methods, so they are not really covered in Rhino/Python documentation. There are lots of Python learning sites and books, here is a page with some resources… I started with Beginning Python by Magnus Lie Hetland, but there are tons of others out there.

Otherwise, the Python online doc is also pretty good, especially if you already have a notion of what you’re looking for and you just need to find the precise function/syntax. This page covers some of the basic types.

Learning some basic Python methods for working with strings, lists, loops, etc. is invaluable.

–Mitch

Thanks for your support Mitch. Your last link did not work, but I am guessing you are referring to the ‘Python online doc > Language Reference’ -page. I will have a closer look.

Max.

Sorry… Fixed.

Hi Mitch,
I did look at the page you suggested, but I am afraid that most of it is way beyond my comprehension, or so involved that it would take me a lot of time to study it, and I would rather spend that time making pretty pictures in Rhino, and creating a little tool in python now and then.
I hope you don’t mind me asking for another explanation. I did go through the string bit in 5.6.1. String Methods and found the str.split bit, but in the script you showed me you are using “parts[-1]” as a result. I cannot place the “-1” argument. I am guessing it means “the last element” or “the rightmost element”, am I right?

It did work as desired though, yielding the name of the sub-layer with the lowest ranking. Here is my script for your entertainment (? :wink:):

#Create Layer Name Text Object for Surfaces,  Max Zuijdendorp, March 2015
import rhinoscriptsyntax as rs

    # Check if a layer "Layer Names Polysrf" exists, if not, add it
    if not rs.IsLayer("Layer Names Polysrf"):
    	rs.AddLayer("Layer Names Polysrf", (0,0,0))
    
    # Make "Layer Names" the current layer
    rs.CurrentLayer("Layer Names Polysrf")
    
    def LEADERCREATE():
    	more=1
    	
    	# Make a list for direction choices
    	choice=["X","-X","Y","-Y"]
    	
    	while (more==1):
    		# Open a list box to select a direction
    		selected=rs.ListBox(choice,message="Select direction of text leader",title="Leader Direction")
    		
    		if selected:
    			# Set the starting point references and the offsets for secondary leader points
    			if (selected=="X"):
    				corner1=1
    				corner2=6
    				offset1=(20,0,10)
    				offset2=(50,0,10)
    			if (selected=="-X"):
    				corner1=0
    				corner2=7
    				offset1=(-20,0,10)
    				offset2=(-50,0,10)
    			if (selected=="Y"):
    				corner1=2
    				corner2=7
    				offset1=(0,20,10)
    				offset2=(0,50,10)
    			if (selected=="-Y"):
    				corner1=0
    				corner2=5
    				offset1=(0,-20,10)
    				offset2=(0,-50,10)
    			# Pick a set of polysurfaces to be identified with the layer name
    			objects = rs.GetObjects("Select Polysurfaces to label", filter=16, preselect=True, select=False)
    			
    			if objects:
    				for obj in objects:
    					bb=rs.BoundingBox(obj)
    					
    					ldrstart=(bb[corner1]+bb[corner2])/2
    					
    					ldrpoint2=rs.PointAdd(ldrstart,offset1)
    					ldrpoint3=rs.PointAdd(ldrstart,offset2)
    					
    					points=[ldrstart,ldrpoint2,ldrpoint3]
    					
    					layername=rs.ObjectLayer(obj)
    					namepart=layername.split("::")
    					layername=namepart[-1]
    					
    					#create your leader
    					rs.AddLeader(points,text=layername)
    		more=rs.MessageBox("Do you want to place more leaders?",buttons=1)
    		
    #Main
    LEADERCREATE()
    
    rs.MessageBox("Script terminated")

Max.

Yes. One of the powerful elements of Python is its tools for working with ordered collections of elements - often termed “iterables”, although that term has a technically more precise definition.

Lists are of course among the iterables, as are tuples - which are just immutable (unchangable) lists. Interestingly enough, strings are also iterable and you can use the same syntax.

Python’s syntax for accessing elements of a list uses square brackets. What you put inside them determines what elements will be returned.

my_list=['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']

#single element access - the index starts at 0
my_list[0] >>> 'The'
my_list[3] >>> 'fox'

#negative numbers count from the other end
my_list[-1] >>> 'dog'
my_list[-2] >>> 'lazy'

#you can get "slices" of the list with a colon:
my_list[3:6] >>>['fox', 'jumped', 'over']
#attention: the last number is the one *after* the last element you want to have.

#the following are tricky:
#(when no number is specified it means go all the way to that end)
my_list[-3:] >>>['the', 'lazy', 'dog']
my_list[:-5] >>>['The', 'quick', 'brown', 'fox']

#[:] copies the entire list
my_list[:] >>>['The', 'quick', 'brown', 'fox', 'jumped', 'over', 'the', 'lazy', 'dog']

#also useful - join the list back into a string (the syntax is tricky):
my_string = " ".join(my_list) >>> 'The quick brown fox jumped over the lazy dog'

#and finally, you can also iterate/slice a string
my_string[10:15] >>>'brown'

HTH, --Mitch

Thanks yet again Mitch, most informative.

Max.

I am afraid I need some more help here. My objective is to convert a string, consisting of digits (like “12”), into another string with the numeric value changed (like “13”). Ideally, the same for a string consisting of a combination of alphabetic characters and digits, like “F12” is changed to “F13” (by calculation).
It seems pretty basic, but I spent quite some time searching in the Python Library and I was not able to find it.

Max.

Hi maxz.

Can this be of help:http://stackoverflow.com/questions/10365225/extract-digits-in-a-simple-way-from-a-python-string

-Willem

Well, you can actually learn Python and make pretty rhino geo by going through the Rhino Python Primer. http://www.rhino3d.com/download/IronPython/5.0/RhinoPython101

Well, if you know the input string will be of a certain specific form - such as FXX where XX are numbers, you can do this relatively easily with basic python string methods. However, if your strings are more complicated and aren’t always the same, probably the only way to solve it rationally is to use regular expressions (regex). But those are fairly advanced concepts, a bit much for beginning programmers.

There are several ways to extract numbers from strings in python. If you KNOW that the string is just digits, you can just simply convert it to integer with the int() method:

onetwothree="123"
fourfivesix="456"

print onetwothree + fourfivesix
>>>'123456'

print int(onetwothree) + int(fourfivesix)
>>> 579

If there are alphanumeric characters, then it gets more complex… If you know for example that there will always be a series of letters followed by a number and you want to increment the number by 1, you can do this: (this is one way, I don’t pretend it’s the best)

f="F12"
numbers=""
letters=""
for element in f:
    if element.isalpha(): letters+=element
    elif element.isdigit(): numbers+=element
    
numbers=str(int(numbers)+1)
print letters + numbers
>>>'F13'

If you can set it up beforehand, it’s always good to have the alpha part of the string and the numeric part of the string separated by a known delimiter. That way it’s easy to find where the alpha ends and the number begins.

orig="F-12"
o_split=orig.split("-")
new=o_split[0]+"-"+str(int(o_split[1])+1)
print new
>>>'F-13'

HTH, --Mitch

@Willem : I have tried to understand and work with your method, stripping my string down to just numbers and converting it to an integer succeeded, but I got stuck on re-converting it to a string. I figured I should use the .format to do that, but alas.

def get_num(x):
	return int(''.join(ele for ele in x if ele.isdigit()))

duplayername="AA333"
newname=""	
result=get_num(duplayername)
print result
newname.format(??????)
print newname

@Helvetosaur : your example is much clearer for me to understand, I will use that. I should have remembered the str() and int() methods, there are enough examples in the RhinoPrimer. :blush:
Thanks for reminding me, and Henry too.

Max.

Hi Max.

You could use string.replace () for that.

newname = duplayername.replace(str (result), str (result+1))

http://www.tutorialspoint.com/python/string_replace.htm

Hth
-Willem

More on…python string split