Study guide
5.1 Character Functions for String Manipulation
SAS Certified Specialist: Base Programming Using SAS 9.4 A00-231
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: SAS Base Programming Exam Overview
1.1 A00-231 Exam Format, Scoring & Test-Day Logistics 1.2 Official Content Areas, Weights & Study Plan
2 Chapter 2: Accessing & Creating SAS Data Structures
2.1 SAS Environment, Syntax Rules, & Data Step Basics 2.2 SAS Data Libraries & the LIBNAME Statement 2.3 Investigating Libraries with PROC CONTENTS & PROC DATASETS 2.4 Importing Delimited & Excel Data with PROC IMPORT 2.5 Raw Data Ingestion with INFILE and INPUT Statements
3 Chapter 3: Managing & Combining SAS Data Sets
3.1 Reading SAS Data Sets with the SET Statement 3.2 Combining Data Sets: Concatenating & Interleaving 3.3 Match-Merging with BY Statements & FIRST./LAST. Processing 3.4 Controlling Data Output & Variable Selection (KEEP, DROP, RENAME, OBS=)
4 Chapter 4: Data Transformation & Conditional Logic
4.1 Creating & Modifying Variables with Assignment Statements 4.2 Modifying Variable Attributes with LENGTH, LABEL, FORMAT & RENAME= 4.3 Conditional Processing: IF-THEN/ELSE Statements & WHERE Subsetting 4.4 Accumulating Totals & Subtotals (RETAIN & Sum Statement) 4.5 Processing Data Iteratively with DO Loops
5 Chapter 5: SAS Functions & Data Type Conversions
5.1 Character Functions for String Manipulation 5.2 Numeric & Mathematical Functions 5.3 Working with SAS Dates, Times, & Intervals 5.4 Reading & Displaying Dates with Informats and Formats 5.5 Explicit & Implicit Data Type Conversions (INPUT & PUT)
6 Chapter 6: Restructuring Data & Program Maintenance
6.1 SAS Array Processing for Multi-Variable Transformations 6.2 Sorting Data Sets with PROC SORT 6.3 Restructuring Data Sets with PROC TRANSPOSE 6.4 Creating & Applying Custom Formats with PROC FORMAT 6.5 Simplifying Programs with Macro Variables (%LET)
7 Chapter 7: Error Handling & Debugging SAS Programs
7.1 SAS Log Analysis & Diagnostic Messages 7.2 Syntax vs. Logic Errors & Phasing 7.3 Debugging Techniques with _ERROR_, _N_, & PUT Statements 7.4 Identifying Logic Errors with the PUTLOG Statement 7.5 Handling Missing Values & Preventing Calculation Propagations
8 Chapter 8: Summary & Detail Data Reporting
8.1 Detail Reporting with PROC PRINT 8.2 Descriptive Statistics with PROC MEANS & PROC SUMMARY 8.3 Frequency & Categorical Analysis with PROC FREQ 8.4 Screening Extreme & Missing Values with PROC UNIVARIATE 8.5 Custom Tabular Reports with PROC REPORT & PROC TABULATE
9 Chapter 9: ODS Output Delivery & Data Export
9.1 Output Delivery System (ODS) Architecture Basics 9.2 Generating PDF, HTML, & RTF Output Destinations 9.3 Exporting Reports to Excel with ODS EXCEL & XLSX 9.4 Generating CSV, PowerPoint & Other ODS Destinations 9.5 Customizing ODS Titles, Footnotes, & Global Options 9.6 Exporting SAS Data Sets with PROC EXPORT & the XLSX Engine
5.1 Character Functions for String Manipulation
Key Takeaways Explain This Topic AI
SUBSTR acts as both a function to extract substrings and a pseudo-variable on the left side of an assignment statement to replace characters in-place.
SCAN extracts words from a character string based on delimiters, where negative count values scan from right to left.
CATX concatenates strings by stripping leading and trailing blanks from arguments and inserting a specified delimiter.
INDEX searches for a target string within a source string and returns the 1-based starting character position, or 0 if not found.
LENGTH returns the length of a character string excluding trailing blanks, whereas LENGTHN returns 0 for a string consisting entirely of blanks.
Last updated: August 2026
5.1 Character Functions for String Manipulation
In SAS DATA step programming, character variables are widely used to store text data such as customer names, addresses, identification codes, and narrative descriptions. SAS provides a robust suite of character functions designed to search, extract, clean, format, and concatenate string values. Understanding how these functions operate on character arguments—and how they handle variable lengths and padding—is fundamental to data preparation and a primary topic on the SAS Certified Specialist Base Programming exam.
1. Substring Extraction & In-Place Assignment: SUBSTR
The SUBSTR (substring) function serves a dual purpose in SAS depending on whether it appears on the right side or the left side of an assignment statement.
Substring Extraction (Right Side of = )
When positioned on the right side of an assignment statement or within an expression, SUBSTR extracts a portion of a character string based on a starting position and an optional length. Syntax: SUBSTR ( string , position , < length > ) \text{Syntax: } \text{SUBSTR}(\textit{string}, \textit{position}, <\textit{length}>) Syntax: SUBSTR ( string , position , < length > )
string : Specifies the character variable, literal, or expression to parse.
position : Specifies the 1-based starting character position. If position exceeds the length of the string, SAS returns a blank string and writes a note to the SAS log.
length : Specifies the number of characters to extract. If omitted, SUBSTR extracts all remaining characters from position to the end of the string. data work.substr_extract;
- code = "ACCT-8904-US";
- dept = substr(code, 1, 4); /* Extracts 'ACCT' */
- num = substr(code, 6, 4); /* Extracts '8904' */
- region = substr(code, 11); /* Extracts 'US' (length omitted) */
- run;
- Substring Modification (Left Side of = )
When SUBSTR appears on the left side of an assignment statement, it functions as a variable modifier, replacing characters in an existing variable starting at the specified position. Syntax: SUBSTR ( variable , position , < length > ) = expression ; \text{Syntax: } \text{SUBSTR}(\textit{variable}, \textit{position}, <\textit{length}>) = \text{expression}; Syntax: SUBSTR ( variable , position , < length > ) = expression ; data work.substr_modify;
- phone = "919-555-0100";
- /* Replace area code 919 with 984 */
- substr(phone, 1, 3) = "984"; /* Result: '984-555-0100' */
- run;
Important
When using SUBSTR on the left side of an assignment, the target variable must already be defined. The length of the target variable does not expand; if the replacement string is longer than the specified length , the extra characters are truncated.
2. Parsing Tokens with the SCAN Function
The SCAN function selects and returns a specific word or token from a character string based on specified delimiters. Syntax: SCAN ( string , count , < ′ delimiters ′ > ) \text{Syntax: } \text{SCAN}(\textit{string}, \textit{count}, <'\textit{delimiters}'>) Syntax: SCAN ( string , count , < ′ delimiters ′ > )
count : Specifies the position of the word to extract. A positive integer selects words counting from left to right. A negative integer selects words counting from right to left.
delimiters : A character string listing the characters that separate words. If omitted, SAS uses default delimiters: blank, period, left parenthesis, plus sign, ampersand, percent sign, vertical bar, dollar sign, asterisk, right parenthesis, semicolon, hyphen, minus sign, slash, comma, and double quotation mark. data work.scan_example;
fullname = "Jane Marie Van-Der-Bilt";
- first_name = scan(fullname, 1, " "); /* 'Jane' */
- middle_name= scan(fullname, 2, " "); /* 'Marie' */
- last_token = scan(fullname, -1, " -"); /* 'Bilt' (scans from right) */
- second_last= scan(fullname, -2, " -"); /* 'Der' */
- run;
Key Behaviors of SCAN :
Consecutive delimiters are treated as a single delimiter.
Leading delimiters are ignored.
If count is greater than the total number of words in the string, SCAN returns a blank value.
In SAS 9.4, if the length of the target variable is not explicitly declared with a LENGTH statement, SAS automatically assigns a default length of 200 bytes to variables created with SCAN .
3. String Concatenation: CAT , CATS , CATT , and CATX
While the traditional concatenation operator (||) joins character strings together, it preserves all leading and trailing blanks. SAS provides dedicated CAT family functions to manage whitespace during concatenation.
- Function Behavior Description Example Code Result
- || Operator Concatenates as-is, retaining all leading & trailing blanks 'A ' || 'B' 'A B'
- CAT(a, b) Equivalent to || , retains leading and trailing blanks cat('A ', 'B') 'A B'
- CATS(a, b) Strips leading and trailing blanks from all arguments cats('A ', ' B') 'AB'
- CATT(a, b) Strips trailing blanks only from all arguments catt('A ', ' B') 'A B'
CATX(dlm, a, b) Strips leading/trailing blanks AND inserts delimiter dlm catx(', ', 'Smith', 'John') 'Smith, John' data work.concatenation;
- length title $ 10 first $ 10 last $ 10 full_name $ 40;
- title = " Dr.";
- first = "Robert ";
- last = "Miller ";
- /* Using CATX strips whitespace and inserts single space */
- full_name = catx(" ", title, first, last); /* Result: 'Dr. Robert Miller' */
- run;
- 4. Searching & Measuring Strings: INDEX & LENGTH
- Finding Substrings with INDEX
The INDEX function searches a source string for a target string and returns the character position of the target's first occurrence. Syntax: INDEX ( source , excerpt ) \text{Syntax: } \text{INDEX}(\textit{source}, \textit{excerpt}) Syntax: INDEX ( source , excerpt ) data work.index_demo;
- text = "The quick brown fox jumps over the lazy dog";
- pos1 = index(text, "brown"); /* Returns 11 */
- pos2 = index(text, "cat"); /* Returns 0 (not found) */
- run;
- Measuring Length: LENGTH vs. LENGTHN
LENGTH(string) : Returns the position of the last non-blank character. If the string is completely blank, LENGTH returns 1 .
LENGTHN(string) : Returns the position of the last non-blank character, but returns 0 if the string is completely blank. data work.length_comparison;
- empty_str = " ";
- len1 = length(empty_str); /* Returns 1 */
- len2 = lengthn(empty_str); /* Returns 0 */
- run;
- 5. Cleaning & Formatting Character Data
SAS offers several utility functions to standardize and clean messy character data. Two of them — TRIM and COMPRESS — are named explicitly in the A00-231 content guide alongside SCAN , SUBSTR , UPCASE , and LOWCASE .
TRIM(string) : Removes trailing blanks only; leading blanks are preserved. TRIM is what you reach for before concatenating with the || operator, because SAS pads every character variable to its full declared length. trim('Cary ') || ', NC' returns 'Cary, NC' , whereas 'Cary ' || ', NC' returns 'Cary , NC' .
COMPRESS(string, <characters>, <modifiers>) : Removes characters from anywhere in the string, not just the ends. With one argument it strips every blank wherever it occurs: compress('9 1 9 5 5 5') returns '919555' . With a second argument it removes exactly the listed characters: compress('(919) 555-0100', '() -') returns '9195550100' . Modifiers add character classes, so compress(id, , 'kd') keeps only digits ( k = keep, d = digits) — the standard one-liner for stripping punctuation out of phone numbers and account codes.
STRIP(string) : Removes both leading and trailing blanks.
COMPBL(string) : Compresses multiple consecutive internal blanks into a single blank space.
PROPCASE(string, <delimiters>) : Capitalizes the first letter of each word and converts all other letters to lowercase.
- UPCASE(string) / LOWCASE(string) : Converts all characters to uppercase or lowercase. data work.compress_demo;
- phone_raw = "(919) 555-0100";
- digits_only = compress(phone_raw, '() -'); /* '9195550100' */
- keep_digits = compress(phone_raw, , 'kd'); /* '9195550100' - keep digits only */
- no_blanks = compress("9 1 9 5 5 5"); /* '919555' - all blanks removed */
- city = "Cary ";
- joined_bad = city || ", NC"; /* 'Cary , NC' */
- joined_good = trim(city) || ", NC"; /* 'Cary, NC' */
- run; data work.clean_data;
- raw_name = " jOHN wILLIAM sMITH ";
- /* Step 1: Reduce multiple blanks to single spaces */
- comp_name = compbl(raw_name); /* ' jOHN wILLIAM sMITH ' */
- /* Step 2: Strip leading/trailing blanks */
- stripped = strip(comp_name); /* 'jOHN wILLIAM sMITH' */
- /* Step 3: Proper capitalization */
- clean_name = propcase(stripped); /* 'John William Smith' */
- run;