String Manipulation Basics
I deal with text parsing every day. It doesn't matter if you are cleaning customer data, building regex patterns, or writing a simple script to rename files. At some point you need to grab the front part of something or the back part. That is where prefix and suffix come in, and they are more annoying than most people admit because every language handles them slightly differently. A prefix is a sequence of characters placed at the beginning of a string. A suffix is a sequence of characters placed at the end. That is the textbook version. In practice, a prefix might be https://, IMG_, or -prod. A suffix might be .png, _backup, or .conf. The boundary matters more than people realize. Sometimes what looks like a prefix is actually embedded in the data. I spent an afternoon last year debugging a batch job that was supposed to strip the country code from phone numbers. The input format was supposed to be a plus sign followed by the digits. Easy enough. But about 14 percent of the records had whitespace before the plus sign, and another chunk had the plus sign encoded as the word PLUS in uppercase. My initial script failed on both. I ended up writing a trim step, then a replace step for the encoded variant, then the actual prefix strip. Takes about four lines of Python if you use lstrip() and removeprefix(), but figuring out which edge cases existed took most of that afternoon.
How To Work With Them In Code
Modern languages have built-in methods for this now. Python has startswith() and endswith(). JavaScript has String.prototype.startsWith() and String.prototype.endsWith(). Go has strings.HasPrefix() and strings.HasSuffix(). Java added startsWith() and endsWith() decades ago. The syntax varies, the logic does not. Here is the basic pattern in Python: filename = "report_final_v2.xlsx"
if filename.endswith(".xlsx"): base = filename.removesuffix(".xlsx") print(base)
Get the Full Details

This prints report_final_v2. It is straightforward when the data is clean. It breaks immediately when someone puts a space before the extension, like report final v2 .xlsx. Then your check fails and your suffix strip either does nothing or leaves garbage behind. For suffix stripping in Python 3.9 and above, removesuffix() is safer than slicing because it does not error if the suffix is missing. Before 3.9 I used filename[:-5] which assumed the suffix was always exactly five characters. That assumption cost me a bug that took two hours to trace. Never assume fixed length on suffixes unless the format is strictly enforced at the source.
Common Pitfalls
Case sensitivity is the first thing that bites people. ".TXT" is not the same as ".txt" in most strict comparisons. Convert to lowercase first if you need case-insensitive matching. In Python you can do filename.lower().endswith(".txt"). In bash you set shopt -s nocaseglob or use ${var,,} to lowercase a variable before comparison. The second pitfall is overlapping patterns. If you are stripping a prefix and then a suffix from the same string, the order matters. Take the string __config_prod.json__. Strip the prefix __ and you get config_prod.json__. Strip the suffix __ and you get __config_prod.json. Do both in the right order and you get config_prod.json. Do them in the wrong order or use the wrong suffix value and you end up with fragments that look valid but are wrong. A third issue that nobody mentions often enough is multi-character delimiters in filenames. People routinely name files like image--duplicate.jpg and then write code that strips everything before the first dash. You just deleted part of the actual name. Use precise prefixes instead of greedy wildcards. Check the exact characters you expect, not just "anything that looks like it could be metadata."
When To Use Regex Instead
Simple prefix and suffix checks work fine for exact matches. Once you need patterns like "any three uppercase letters followed by digits," regex becomes more practical. But regex is heavier and harder to read. Use it when the pattern requires it, not because you want to look clever. I once replaced a chain of six nested startswith() and endswith() calls with a single compiled regex pattern. Execution time dropped from roughly 0.8 milliseconds per record to about 0.3 milliseconds across a dataset of 120,000 rows. That is real. But the regex was harder for the next person on the team to modify. If the team is small and the pattern rarely changes, stick with the explicit methods.

Limitations You Should Know About
Prefix and suffix operations assume your string boundaries are well defined. They fail when the boundary is ambiguous. File systems do not enforce naming conventions. Email addresses vary by provider. Log lines mix formats within the same file. In those cases, prefix and suffix checks alone are not enough. You need validation layers, fallback parsing, or manual overrides. Another hard limitation: these operations are positional. They do not understand semantic meaning. A string ending in .txt might be a text file, but it might also be a configuration file that someone renamed incorrectly. The code will still strip the suffix. Always validate the content type separately if correctness matters.
Quick Reference For Common Languages
Python: str.startswith(prefix), str.endswith(suffix), str.removeprefix(), str.removesuffix(). JavaScript: str.startsWith(), str.endsWith(), str.slice() for removal. Bash: [[ $str == prefix* ]], ${str#prefix}, ${str%suffix}.
Go: strings.HasPrefix(), strings.HasSuffix(), strings.TrimPrefix(), strings.TrimSuffix(). Rust: str.starts_with(), str.ends_with(), str.strip_prefix(), str.strip_suffix(). All of these follow the same logic. Pick the one that fits your stack and test it against dirty input before you ship it.
