String Manipulation
Master Visual Basic 2026's comprehensive text-processing toolkit — concatenation, extraction (Left, Right, Mid), searching (InStr, Contains, IndexOf), transformation (UCase, LCase, Trim, Replace), splitting and joining, string interpolation, StringBuilder for performance, and .NET 10 improvements — with GitHub Copilot assistance throughout.
String class methods; for building strings in a loop use StringBuilder for much better performance. VB 2026 / .NET 10 adds string interpolation ($"…{expr}…") as the preferred way to build formatted strings, plus raw string literals and span-based methods for high-performance text processing.
12.1 String Concatenation
VB 2026 provides two concatenation operators: & and +. Always prefer & for string concatenation — it works safely with any data type by converting it to string first. The + operator performs addition when both operands are numeric, which can cause unexpected bugs.
' ── & operator — safe, always concatenates ───────────── Dim firstName As String = "Alice" Dim lastName As String = "Wong" Dim fullName = firstName & " " & lastName ' "Alice Wong" ' ── + operator — risky with mixed types ──────────────── Dim result1 = "Score: " + 95.ToString() ' ✔ OK — explicit ToString() Dim result2 = "Value: " & 42 ' ✔ & converts 42 to "42" automatically ' ── String interpolation — the modern VB 2026 way ────── Dim age = 25 Dim score = 95 Dim gpa = 3.85 lblInfo.Text = $"{firstName} {lastName} — Age: {age}, Score: {score}, GPA: {gpa:F2}" ' → "Alice Wong — Age: 25, Score: 95, GPA: 3.85" ' Interpolation with expressions and format specs Dim price = 29.9D lblPrice.Text = $"Total: {price * 1.06:C}" ' currency format → "Total: RM31.65" lblDate.Text = $"Today: {DateTime.Today:dd/MM/yyyy}" ' ── += to append to existing string ──────────────────── Dim report As String = "" report &= "Name: Alice" & vbCrLf report &= "Score: 95" & vbCrLf txtReport.Text = report
12.2 Essential String Functions
Important Difference: VB Functions vs .NET Methods
VB 2026 supports both the classic VB string functions (Left, Mid, InStr, Len) and .NET String methods (.Substring(), .IndexOf(), .Length). The key difference is indexing: VB functions use 1-based positions; .NET methods use 0-based positions.
Dim s = "Visual Basic 2026" ' ── VB functions — 1-based ───────────────────────────── Dim vbLen = Len(s) ' 17 Dim vbLeft = Left(s, 6) ' "Visual" (first 6 chars) Dim vbRight = Right(s, 4) ' "2026" (last 4 chars) Dim vbMid = Mid(s, 8, 5) ' "Basic" (start at pos 8, take 5) Dim vbFind = InStr(s, "Basic") ' 8 (1-based position) ' ── .NET String methods — 0-based ───────────────────── Dim netLen = s.Length ' 17 Dim netLeft = s.Substring(0, 6) ' "Visual" (start 0, length 6) Dim netRight = s.Substring(s.Length - 4) ' "2026" Dim netMid = s.Substring(7, 5) ' "Basic" (0-based start = 7) Dim netFind = s.IndexOf("Basic") ' 7 (0-based index) ' ── Consistency tip: pick one style and stick to it ──── ' .NET methods work everywhere; VB functions need Imports Microsoft.VisualBasic
Mid("Hello", 1, 3) returns "Hel" (VB, starts at 1). "Hello".Substring(0, 3) also returns "Hel" (.NET, starts at 0). Mixing styles causes off-by-one errors. VB 2026 best practice: use .NET methods (.Substring(), .IndexOf()) for new code — they work everywhere including Blazor and MAUI. Use VB functions (Mid, InStr) only when working with legacy VB code.
Type a string and use Left/Right/Mid/Substring to extract portions — the visualiser highlights exactly which characters are selected.
12.3 Searching Strings
Dim email = "[email protected]" ' ── Contains / StartsWith / EndsWith ────────────────── If email.Contains("@") Then lblResult.Text = "Valid email format" End If If email.EndsWith(".com") Then lblDomain.Text = "Commercial domain" End If ' ── IndexOf — find position (0-based), -1 if not found ─ Dim atPos = email.IndexOf("@") ' 10 Dim dotPos = email.LastIndexOf(".") ' 18 (last dot) ' Extract username and domain using IndexOf If atPos > 0 Then Dim username = email.Substring(0, atPos) ' "alice.wong" Dim domain = email.Substring(atPos + 1) ' "example.com" lblUser.Text = $"User: {username}" lblDomain.Text = $"Domain: {domain}" End If ' ── InStr — VB-style search (1-based, 0 if not found) ─ Dim pos = InStr(email, "@") ' 11 (1-based) If pos > 0 Then Dim user = Left(email, pos - 1) ' "alice.wong" End If ' ── Case-insensitive comparison ──────────────────────── If String.Compare(email, "[email protected]", True) = 0 Then ' Third arg True = ignore case End If ' ── OrdinalIgnoreCase (most reliable for comparisons) ── If email.Equals("[email protected]", StringComparison.OrdinalIgnoreCase) Then lblResult.Text = "Emails match (case-insensitive)" End If
12.4 Transforming Strings
Dim input = " Hello, Visual Basic 2026! " ' ── Case conversion ──────────────────────────────────── Dim upper = input.ToUpper() ' " HELLO, VISUAL BASIC 2026! " Dim lower = input.ToLower() ' " hello, visual basic 2026! " Dim proper = StrConv(input, VbStrConv.ProperCase) ' " Hello, Visual Basic 2026! " ' ── Trim whitespace ──────────────────────────────────── Dim trimmed = input.Trim() ' "Hello, Visual Basic 2026!" (both ends) Dim trimLeft = input.TrimStart() ' removes leading spaces only Dim trimEnd = input.TrimEnd() ' removes trailing spaces only ' Good practice: always Trim() user input from TextBoxes Dim name = txtName.Text.Trim() ' ── Replace ──────────────────────────────────────────── Dim phone = "012-345-6789" Dim noHyphen = phone.Replace("-", "") ' "0123456789" — remove all hyphens Dim masked = phone.Replace(phone.Substring(3, 3), "***") ' mask middle digits ' ── PadLeft / PadRight ───────────────────────────────── Dim id = "42" Dim padded = id.PadLeft(6, "0"c) ' "000042" — zero-pad to 6 digits Dim padR = "Alice".PadRight(12, "."c) ' "Alice......." — table alignment ' ── Reverse a string (no built-in, use LINQ) ─────────── Dim rev = New String(input.Trim().Reverse().ToArray()) ' → "!6202 cisaB lausiV ,olleH"
Apply transformation functions to your text — case conversion, trim, replace, pad, and reverse.
12.5 Split and Join
Split() breaks a string into an array using a delimiter — perfect for parsing CSV data, user input lists, file paths, and email addresses. String.Join() does the reverse, assembling an array back into a single string with a separator.
' ── Split by single delimiter ────────────────────────── Dim csv = "Alice,Bob,Charlie,Diana,Eve" Dim names() = csv.Split(","c) ' {"Alice","Bob","Charlie","Diana","Eve"} For Each name As String In names lstNames.Items.Add(name) Next ' ── Split with multiple delimiters ──────────────────── Dim data = "Name:Alice;Age:25;City:KL" Dim pairs() = data.Split({";"c, ":"c}) ' {"Name","Alice","Age","25","City","KL"} ' ── Split with options — remove empty entries ────────── Dim messy = "one,,two,,,three" Dim clean() = messy.Split({","c}, StringSplitOptions.RemoveEmptyEntries) ' {"one","two","three"} — empty parts removed ' ── Parse CSV line into structured data ──────────────── Dim record = "STU001,Alice Wong,85,92,78" Dim fields = record.Split(","c) Dim id = fields(0) ' "STU001" Dim student = fields(1) ' "Alice Wong" Dim mark1 = CInt(fields(2)) ' 85 ' ── Join — reverse of split ──────────────────────────── Dim parts() = {"Visual", "Basic", "2026"} Dim joined = String.Join(" ", parts) ' "Visual Basic 2026" Dim path = String.Join("/", {"C:", "Users", "Alice", "Documents"}) ' "C:/Users/Alice/Documents" ' ── Split path components ────────────────────────────── Dim filePath = "C:\Users\Alice\report.docx" Dim pathParts = filePath.Split("\"c) Dim fileName = pathParts(pathParts.Length - 1) ' "report.docx"
Enter a delimited string, choose a delimiter, split it apart — then re-join with a different separator.
12.6 StringBuilder — High-Performance String Building
Because strings are immutable, every &= in a loop creates a new string object and copies all previous characters. For a loop of N iterations this is O(N²) work. StringBuilder uses a mutable internal buffer — appending is O(1) amortized. Use it whenever you build a string inside a loop.
Imports System.Text ' ── The SLOW way — creates thousands of string objects ─ Dim report As String = "" For i = 1 To 1000 report &= $"Line {i}: data{vbCrLf}" ' ✘ slow — 1000 new string objects Next ' ── The FAST way — StringBuilder with mutable buffer ─── Dim sb As New StringBuilder() For i = 1 To 1000 sb.AppendLine($"Line {i}: data") ' ✔ fast — appends to internal buffer Next Dim result = sb.ToString() ' one string at the end ' ── StringBuilder methods ────────────────────────────── Dim sb2 As New StringBuilder("Hello") sb2.Append(", World") ' "Hello, World" sb2.AppendLine("!") ' appends + newline sb2.Insert(5, " Beautiful") ' "Hello Beautiful, World\n!" sb2.Replace("World", "VB 2026") ' find/replace in buffer sb2.Remove(0, 6) ' remove 6 chars from pos 0 Dim len = sb2.Length ' current length sb2.Clear() ' reset to empty ' ── Practical: generate HTML table ──────────────────── Dim html As New StringBuilder() html.AppendLine("<table>") For Each row As String In dataRows html.AppendLine($" <tr><td>{row}</td></tr>") Next html.AppendLine("</table>") txtOutput.Text = html.ToString()
12.7 New in VB 2026 / .NET 10
' ── Raw string literals (multi-line, no escape needed) ─ Dim json = """ { "name": "Alice", "age": 25, "city": "Kuala Lumpur" } """ ' Triple quotes — no need to escape internal quotes ' ── String.Equals with OrdinalIgnoreCase ─────────────── Dim isMatch = "Hello".Equals("hello", StringComparison.OrdinalIgnoreCase) ' True ' ── Span-based methods — zero-allocation parsing ─────── Dim line = "Alice,25,KL".AsSpan() Dim comma1 = line.IndexOf(","c) Dim name = line.Slice(0, comma1).ToString() ' "Alice" — no string allocation ' ── String.Create — efficient string construction ────── Dim id = String.Create(8, "user", Sub(span, prefix) prefix.CopyTo(span) "0001".CopyTo(span.Slice(prefix.Length)) End Sub) ' id = "user0001" — no intermediate strings ' ── SearchValues — fast multi-char scanning (.NET 10) ── Dim digits = System.Buffers.SearchValues.Create("0123456789") Dim phone = "Call 012-345-6789 now" Dim firstNum = phone.AsSpan().IndexOfAny(digits) ' 5 — first digit position ' ── String.IsNullOrWhiteSpace — essential input guard ── If String.IsNullOrWhiteSpace(txtName.Text) Then lblError.Text = "Name is required" Return End If
- Always Trim() user input from TextBoxes before any processing
- Use
String.IsNullOrWhiteSpace()instead of= ""to guard againstNothingand whitespace-only input - Prefer string interpolation (
$"…{expr}…") over&chains — more readable and slightly faster in .NET 10 - Use
StringBuilderwhen building strings in a loop with more than ~10 iterations - Use
StringComparison.OrdinalIgnoreCasefor case-insensitive comparisons — it is faster and culturally safe - Use
&(not+) for string concatenation to avoid type confusion bugs
Parse an email address into components using IndexOf, Substring, and Split. Also parse a full name into first/last using string functions.
Enter any text and get a full analysis — length, word count, character frequencies, InStr search, and palindrome detection.
12.8 GitHub Copilot — String Assistance
' Parse a CSV line "id,name,age,score" from txtCSV. Validate each field, then display in 4 Labels'' Parse a CSV line "id,name,age,score" from txtCSV. Validate each field, then display in 4 Labels Dim line = txtCSV.Text.Trim() Dim fields = line.Split(","c) If fields.Length < 4 Then lblError.Text = $"⚠ Expected 4 fields, got {fields.Length}" Return End If Dim id = fields(0).Trim() Dim name = fields(1).Trim() Dim age As Integer Dim score As Double If Not Integer.TryParse(fields(2).Trim(), age) Then lblError.Text = "⚠ Age must be a whole number." Return End If If Not Double.TryParse(fields(3).Trim(), score) Then lblError.Text = "⚠ Score must be a number." Return End If lblID.Text = $"ID: {id}" lblName.Text = $"Name: {name}" lblAge.Text = $"Age: {age}" lblScore.Text = $"Score: {score:F1}"
' Check password strength: at least 8 chars, contains uppercase, lowercase, digit, and special char. Show strength as Weak/Fair/Strong/Very Strong'' Check password strength: at least 8 chars, contains uppercase, lowercase, digit, and special char. Show strength as Weak/Fair/Strong/Very Strong Dim pwd = txtPassword.Text Dim hasUpper = pwd.Any(Function(c) Char.IsUpper(c)) Dim hasLower = pwd.Any(Function(c) Char.IsLower(c)) Dim hasDigit = pwd.Any(Function(c) Char.IsDigit(c)) Dim hasSpecial = pwd.Any(Function(c) Not Char.IsLetterOrDigit(c)) Dim isLong = pwd.Length >= 8 Dim score = ({isLong, hasUpper, hasLower, hasDigit, hasSpecial}).Count(Function(b) b) Dim strength = Select Case score Case 0, 1 : "Weak" Case 2, 3 : "Fair" Case 4 : "Strong" Case Else : "Very Strong" End Select lblStrength.Text = $"Strength: {strength} ({score}/5 criteria met)"
Try these in the Copilot Chat panel while working with strings:
- "Validate a Malaysian phone number format (012-345-6789) using Contains, StartsWith, and Length checks"
- "Parse a full name 'firstname middlename lastname' and create initials like 'A.M.W.'"
- "Build a word frequency counter for the text in a RichTextBox using Split and Dictionary(Of String, Integer)"
- "Use StringBuilder to generate a formatted report of student marks with name, score, and grade columns"
📘 Lesson Summary
- Use & (not
+) for string concatenation — it safely converts any type to String automatically. Prefer string interpolation ($"…{expr}…") for readable, formatted strings. - VB functions (
Left,Right,Mid,InStr) use 1-based positions. .NET methods (Substring,IndexOf) use 0-based positions — never mix the two styles in the same expression. Contains(),StartsWith(),EndsWith()are the most readable search methods. UseIndexOf()when you need the actual position; it returns-1if not found.- Always call
.Trim()on user input from TextBoxes. UseString.IsNullOrWhiteSpace()as the guard check — it handlesNothing, empty string, and whitespace-only strings. Split(","c)converts a delimited string to an array.String.Join(sep, array)reverses this. UseStringSplitOptions.RemoveEmptyEntriesto clean up empty tokens.- Use StringBuilder in loops — it avoids creating N² string copies. Call
.AppendLine(),.Insert(),.Replace(), and.ToString()at the end. - VB 2026 / .NET 10 adds raw string literals (triple-quoted, no escape needed), Span-based methods for zero-allocation parsing, and
SearchValuesfor fast multi-character scanning. - For case-insensitive comparisons use
StringComparison.OrdinalIgnoreCase— it is faster and avoids culture-specific bugs (e.g. Turkish lowercase İ).
Exercises
Exercise 12.1 — Text Processing App
- Build a form with a multiline TextBox for input and a Label/TextBox area for output
- Add buttons for: ToUpper, ToLower, ProperCase, Trim All Lines, Count Words, Count Characters (no spaces)
- Add a Find/Replace section with two TextBoxes and a Replace button that uses
.Replace() - Display word count by splitting on spaces and using
StringSplitOptions.RemoveEmptyEntries - Copilot challenge: Ask Copilot to "add a character frequency table showing how many times each letter appears, sorted by frequency"
Exercise 12.2 — CSV Student Record Parser
- Let the user paste a CSV line in the format: ID,Name,Math,Science,English
- Use
Split(","c)to parse the fields. Validate each field with TryParse where appropriate - Calculate the average mark and display a formatted report using string interpolation
- Use
PadRight()on the name column andPadLeft()on number columns for table alignment - Copilot challenge: Ask Copilot to "let the user paste multiple CSV lines and process them all into a ListBox report"
Exercise 12.3 — Password Strength Meter
- Build a password input TextBox that checks strength in real-time as the user types
- Check for: Length ≥ 8, Has uppercase, Has lowercase, Has digit, Has special character
- Show a coloured ProgressBar or label: Weak (red), Fair (orange), Strong (yellow), Very Strong (green)
- Use
Char.IsUpper(),Char.IsLower(),Char.IsDigit(), andChar.IsLetterOrDigit() - Copilot challenge: Ask Copilot to "add a 'Show/Hide password' CheckBox that toggles between PasswordChar = '*' and empty"
Related Resources
← Lesson 11
Math Operations — arithmetic operators and the Math class.
Lesson 13 →
If..Then..Else — conditional logic and program flow control.
MS Docs — VB Strings
Complete reference for string features and functions in VB.NET.
MS Docs — StringBuilder
StringBuilder class — methods, performance, and usage patterns.
Featured Books
Visual Basic 2022 Made Easy
Comprehensive coverage of string manipulation functions with step-by-step text-processing projects and practical applications.
View on Amazon →
VB Programming With Code Examples
48 fully-explained VB.NET programs including text editors, CSV parsers, and string-intensive data processing applications.
View on Amazon →