Watch the video above, then read on for the detail. This post walks through string slicing in depth, with finance examples you can use immediately.
What String Slicing Is and Why It Matters in Finance
String slicing is the ability to extract a contiguous section of characters from a string. Instead of reaching for a single character at one position (which indexing does), you grab a range.
In finance, this matters because text data is often concatenated or fixed width. A trade confirmation might pack the date, account code, and currency into one field. A settlement message might encode the ISIN, quantity, and settlement date in a specific byte range. A data feed might give you a reference code where the last three characters are always the entity code. Slicing lets you pull those sections out cleanly, without regex or loops.
How Python Indexes Strings: Zero Based and Exclusive Upper Bound
Before you slice, you need to understand how Python counts.
Python uses zero based indexing. The first character is at position 0, the second at position 1, and so on.
account = "ACC123456789"
print(account[0]) # A
print(account[1]) # C
print(account[2]) # C
print(account[3]) # 1
The second key rule is the exclusive upper bound. When you specify a range, Python includes the start position but excludes the stop position. This feels odd at first, but it makes ranges intuitive: the length of the slice is always (stop minus start).
account = "ACC123456789"
print(len(account)) # 12
# Get characters from position 0 to 3 (positions 0, 1, 2; position 3 is excluded)
print(account[0:3]) # ACC
# Get characters from position 3 to 6 (positions 3, 4, 5; position 6 is excluded)
print(account[3:6]) # 123
# Length is 6 - 3 = 3 characters
Think of indices as marking the positions between characters. Index 0 is before the first character, index 3 is after the third character. Your slice spans from one position to another.
The exclusive upper bound is intentional design. It means slice(a, b) is always b minus a characters long, and slice(a, b) plus slice(b, c) cleanly covers slice(a, c). It takes practice to feel natural, but it pays off.
The Slicing Syntax: Start, Stop, and Step
The basic slicing syntax is string[start:stop:step].
start is the index where the slice begins (inclusive). If you omit it, Python defaults to 0.
stop is the index where the slice ends (exclusive). If you omit it, Python defaults to the length of the string, which means "go to the end".
step is the interval between characters you want to include. If you omit it, the default is 1 (every character). You can use step to skip characters.
isin = "IE00B4L5Y983"
# Start from position 0, stop at position 2 (positions 0, 1)
print(isin[0:2]) # IE
# Start from position 2, go to the end
print(isin[2:]) # 00B4L5Y983
# From the start to position 2
print(isin[:2]) # IE
# The whole string
print(isin[:]) # IE00B4L5Y983
# Every 2nd character, from position 0 to 10
print(isin[0:10:2]) # I0BL9
In practice, you will use string[:n] for the first n characters, string[n:] for everything from position n onward, and string[a:b] to grab the middle.
Negative Indices: Counting Backwards from the End
Python also lets you count backwards from the end of the string using negative indices. The last character is at position -1, the second to last is at position -2, and so on.
settlement_msg = "GBPUSDEUR"
# Last character
print(settlement_msg[-1]) # R
# Last 3 characters
print(settlement_msg[-3:]) # EUR
# Everything except the last 3 characters
print(settlement_msg[:-3]) # GBPUSD
# Last 6 characters, but skip the last one
print(settlement_msg[-6:-1]) # DUSE
This is useful in finance because you often know a suffix. The last three characters of a code might be a currency. The last four digits might be a year. You can slice without needing to know the total length.
trade_ref = "TRD202500154789GBP"
# Extract the currency (last 3 characters)
currency = trade_ref[-3:]
print(currency) # GBP
# Extract everything except the currency
base_ref = trade_ref[:-3]
print(base_ref) # TRD202500154789
Step Values and Stride Patterns
The step parameter is less common but powerful for fixed format data or when you need to extract every nth character.
A positive step moves forward through the string. A negative step moves backward.
# Every 2nd character
account_code = "A1C2C3D4E5F6"
print(account_code[::2]) # ACDEF
# Every 3rd character, starting from position 1
print(account_code[1::3]) # 1D5
# Reverse the entire string
print(account_code[::-1]) # 6F5E4D3C2C1A
A weekly note on treasury, liquidity and practical Python. No spam, unsubscribe any time.
Reversing a string is rare in finance, but it does come up. Extracting every nth character appears when you have a legacy fixed format feed where positions are encoded in a pattern.
# Example: alternating digit and code in a reference string
ref = "1A2B3C4D5E"
# Extract just the digits (positions 0, 2, 4, 6, 8)
digits = ref[::2]
print(digits) # 12345
# Extract just the letters (positions 1, 3, 5, 7, 9)
letters = ref[1::2]
print(letters) # ABCDE
Real Finance Examples: ISIN, Trade Dates, and Account Codes
Now apply these tools to actual finance tasks.
Extracting the ISIN Prefix
An ISIN is 12 characters: a 2 letter country code, a 9 character code, and a 1 digit check digit. You often need just the country or the base code.
isin = "IE00B4L5Y983"
# Country code (first 2 characters)
country = isin[:2]
print(country) # IE
# Base code (characters 2 to 11, which is positions 2 to 11)
base_code = isin[2:11]
print(base_code) # 00B4L5Y98
# Check digit (last character)
check_digit = isin[-1]
print(check_digit) # 3
# Everything except check digit
isin_without_check = isin[:-1]
print(isin_without_check) # IE00B4L5Y98
Parsing a Trade Date from a Confirmation String
Settlement messages often pack dates in YYYYMMDD format within a longer string. You need to extract and parse it.
confirmation = "TRADE20250318GBP50000GBPUSD123456"
# Date is at positions 5 to 13 (YYYYMMDD = 8 characters)
date_str = confirmation[5:13]
print(date_str) # 20250318
# Split the date
year = date_str[0:4]
month = date_str[4:6]
day = date_str[6:8]
print(f"{day}/{month}/{year}") # 18/03/2025
Isolating Account Identifiers from Concatenated Feeds
A data feed might give you a concatenated account identifier where the first 4 characters are the bank code, the next 6 are the account number, and the last 4 are the sub account.
account_feed = "GBAB123456AB01"
# Bank code (first 4)
bank_code = account_feed[:4]
print(bank_code) # GBAB
# Account number (next 6)
account_num = account_feed[4:10]
print(account_num) # 123456
# Sub account (last 4)
sub_account = account_feed[10:]
print(sub_account) # AB01
# Or, using negative indices for the sub account
sub_account = account_feed[-4:]
print(sub_account) # AB01
Common Slicing Patterns and Edge Cases
A few patterns you will use repeatedly.
First n characters:
value = "GBPUSDEUR"
print(value[:3]) # GBP
Last m characters:
value = "GBPUSDEUR"
print(value[-3:]) # EUR
Characters from position a to b:
value = "GBPUSDEUR"
print(value[2:5]) # PUS
All characters except the first and last:
value = "GBPUSDEUR"
print(value[1:-1]) # BPUSDEU
Handling Edge Cases
What happens if the string is shorter than you expect? Python does not raise an error; it just gives you what it can.
short_value = "GBP"
# Ask for positions 0 to 10, but the string only has 3 characters
print(short_value[0:10]) # GBP
# Ask for the last 10 characters of a 3 character string
print(short_value[-10:]) # GBP
# Ask for position 5 onward (past the end)
print(short_value[5:]) # (empty string)
This is forgiving, but you should be aware of it. If you are parsing a field and expect 8 characters, but get fewer, the slice will not fail; it will just give you what is there. This is good for robustness but means you need to validate the input length if exact positions matter.
# Defensive approach: check length before slicing
trade_date_str = "20250318"
if len(trade_date_str) == 8:
year = trade_date_str[0:4]
month = trade_date_str[4:6]
day = trade_date_str[6:8]
print(f"{day}/{month}/{year}")
else:
print("Invalid date format")
When to Slice and When to Use Other Tools
Slicing is clean and fast for fixed positions. But it is not always the best tool.
Use slicing when:
- The data has fixed width fields (known character positions).
- You know exactly where the substring starts and stops.
- Performance matters and you are processing large volumes (slicing is fast).
Consider alternatives when:
- The delimiter or separator is inconsistent. Use
split()instead. - You need to find a pattern or condition. Use
find()orindex()to locate it first, then slice, or use regex. - You need to extract multiple fields with different rules. A regex or a structured parse might be cleaner.
# Good use of slicing: fixed width
isin = "IE00B4L5Y983"
country = isin[:2]
# Better to use split: delimiter based
value = "IE|00B4L5Y983|3"
parts = value.split("|")
country = parts[0]
isin_code = parts[1]
# Consider regex: complex pattern
trade_msg = "Trade ID TRD123456 on 2025-03-18 for GBP 50000"
import re
match = re.search(r"(\d{4}-\d{2}-\d{2})", trade_msg)
if match:
date = match.group(1)
In practice, you will often combine these tools. Slice to grab a fixed section, then split that section, or use regex to validate it. The best approach depends on your data format and how much control you have over it.
Practical Takeaway
String slicing is your primary tool for extracting substrings when the data is structured and positions are known. Learn the syntax: string[start:stop:step], remember that Python counts from zero and the upper bound is exclusive, and use negative indices to work backward from the end.
For your next parsing task, write out the positions on paper. Know exactly which characters you need. Then use slicing to pull them. For data feeds you parse regularly, comment the character positions in your code so the next person (or you, three months later) understands what each slice extracts.
If you are working with account codes, ISIN prefixes, or fixed format settlement messages, slicing will save you time and make your code readable. If the data is not fixed width or uses delimiters, reach for split() first.

The Complete Python Course
Welcome to the most practical and beginner friendly Python Bootcamp Course on YouTube.
Take the courseGet the next one in your inbox
A weekly note across Finance & Treasury, Innovation & Automation and Career Development. No spam, unsubscribe any time.
Notes across finance and treasury, innovation and automation, and career development, written by practitioners who do the work.
