Recognizing prefixes/suffixes in Python?

Hi all,

Firstly, I’m not sure of the terminology, so let me know if I’m being unclear or imprecise. If I have several objects in a blend file, say:

brick_1x2_md
brick_1x2_md.001
brick_1x2_md.002
brick_1x2_hi
brick_1x2_hi.001
brick_1x2_hi.002

How do I get a script to select or recognize all of the _md or _hi objects. For example, so I could set all _md objects invisible, or all _hi objects invisible?

Thanks in advance!

-Stefan-

Following code does naive matching. Give it a go.


from Blender import Scene 
 
scn = Scene.GetCurrent() 
 
for ob in scn.objects: 
    print ob.name 
    if ob.name.find('_hi') >= 0: 
        print 'got _hi' 
    if ob.name.find('_me') >= 0: 
        print 'got _me'

The problem with above solution is that it matches cases like “evil_object_me_hi” in both “_me” and “_hi” case. There are multiple ways to overcome this issue though. One way would be to split the string based on _ and then check if the last portion has matching element:


...
test_str = "foo_me_hi"
split_str = test_str.split("_")
last_part = split_str[-1]
last_part.find("hi") # should print zero

The problem with above code is that it matches also “foobar_hihi” which is not desired. Probably the easiest way to handle all the special cases is to use a suitable regex operation (http://www.python.org/doc/2.5.2/lib/module-re.html) but if you are sure you are not going to run into those nasty cases, either of the above solutions might do the trick at least for some time.

Awesome, thanks for the info!

-Stefan-

Naively, I prefer write :


from Blender import Scene 
scn = Scene.GetCurrent() 
for ob in scn.objects: 
    print ob.name 
    if ob.name.find('_hi') == len(ob.name)-3: 
        print 'got _hi' 
    if ob.name.find('_me') == len(ob.name)-3: 
        print 'got _me'

jms: That won’t work if the substring is present more than once, you’d need to use rfind() for that, but then again, you’re probably better off using endswith()

If you want to get rid of the .0001, you can use this to strip out them out:


name = ".".join(ob.name.split(".")[:-1])

Martin

But, of course, less naively, I prefer write for a suffix :


from Blender import Scene 
scn = Scene.GetCurrent() 
for ob in scn.objects: 
    print ob.name 
    if ob.name.rfind('_hi') == len(ob.name)-3: 
        print 'got _hi' 
    if ob.name.rfind('_me') == len(ob.name)-3: 
        print 'got _me'

Even less naively, you’d write:

if ob.name.endswith('_hi'):

Martin

Really shorter.

It’s more optimal too. endswith will stop looking if the last characters don’t match, not so with rfind or find.

endswith also carries more semantical values than rfind in this context which enables a better implementation of the method. When there’s a proper tool for the job, why bang on a screw with a hammer?

Martin