Separate Alphanumeric string from input box into 3 separate strings

I need to separate the text to pass the information to 3 different tags. string length will be different so i can’t just use a split or substring to separated.
What i’m trying to achieve with this is to access any in a Siemens PLC, for example a Technician would type in the input boxes “M500.0” then I need to get “M”,“500”,“0”, all three separated, which i could do if the length of the string was always the same, but they can also type “M1000.7” or “MW300” or “PIW346” so here is where i run into my problem. As I can’t use the same code for all this variations. ideally what i would be looking for, would be something that would get the index of the last letter or the first number and do the first split there , then use the “.” for the other split, if there is a “.” , in the case of MW and PIW I don’t even need to split a second time because there is not bit value.

This is my ignition Screen.

Originally I had design this in a Weintek Hmi using a Dropdown to select the Data type (M, MW, I, Q,PIW and so on) then use two different input box to type the rest. i pass this to a S7 STL code and from there i read the status of the selected address and give the Status back. this way Maintenance tech can troubleshoot without the need of going into the PLC. With Ignition I thought it would be better to do Multiple status check as the same time for different addresses. that way they can probably check the status of a full network by just typing the address that they have on the printed program, this is a much needed solution for our company.

Using the dropdown and two different input boxes does not make much sense as i can have them just type the address in an input and i separate into 3. well at least that is what I wanted to do. but so far no luck.

so if anyone can help it would be really appreciated. and i would gladly provide the STL code if someone wants it for them. this a anypointer STL code to get any address in the PLC without the need of opening a DB or anything. and it would work on any program as long as the FC is called.

Thanks in advance.


My idea is to check every characters of the whole string and divide them into letters and numbers
Here it is the script:

You can do it with strings directly:

a = 'PIW346'

numbers = ''
letters = ''

for x in range(len(a)):
	if a[x].isnumeric():
		numbers += a[x]
	elif a[x].isalpha():
		letters += a[x]
	elif a[x] == '.':
		bit_value = a[x+1]

print numbers
print letters
print bit_value

or you can do it with lists:

a = 'M300.0'

numbers = []
letters = []

for x in range(len(a)):
	if a[x].isnumeric():
	elif a[x].isalpha():
	elif a[x] == '.':
		bit_value = a[x+1]

print numbers
print letters
print bit_value

I tested it with all the “possibilities” you gave us in the post and it worked all the time.

Hope this will help you


1 Like

I will test tomorrow morning but yes it make sense and it should work . Thanks so much .

Another option is to use regex and split. This is a bit more verbose than it can be but much more readable for it.

import re

testS = 'M1000.7'

letterMatch = r'(\D*\B)'
numberMatch = r'((?:(?!.).)*\d+)'

# Find all letters from start of string until the first digit. Returns an array of one in this case
letters = re.findall(letterMatch,testS)[0]
# First group captured is all numbers after the letters but before the dot
numbers = re.findall(numberMatch,testS)[0]
# If there is a dot, grabs everything after it
bit = ''
if '.' in testS:
    bit = testS.split('.')[1]

print letters # prints M
print numbers # prints 1000
# bit evaluates to false if it is empty
if bit: print bit # prints 7

All three variables will be strings just in case that matters but they will be easily castable


Different regex approach (I would also recommend regex for this):
Group 1 is the data type, group 2 is the address, group 3 (if present) is the bit address.


thanks everyone. it works with any of those options.