惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
博客园 - 【当耐特】
IT之家
IT之家
M
MIT News - Artificial intelligence
酷 壳 – CoolShell
酷 壳 – CoolShell
Martin Fowler
Martin Fowler
V
Visual Studio Blog
F
Fortinet All Blogs
The Cloudflare Blog
Last Week in AI
Last Week in AI
博客园 - 司徒正美
G
Google Developers Blog
Vercel News
Vercel News
爱范儿
爱范儿
小众软件
小众软件
WordPress大学
WordPress大学
I
InfoQ
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
MongoDB | Blog
MongoDB | Blog
A
About on SuperTechFans
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
C
Check Point Blog
Apple Machine Learning Research
Apple Machine Learning Research
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How To Limit The Number Of Words Or Characters Shown With...
AMPscript Ni · 2026-05-07 · via DEV Community

Ever had a scenario where you were putting a product name or some other kind of dynamic content into a subject line, and you wanted to only show the first X words or characters? Or featuring article content in an email and wanted to include a short blurb with the first X words as a preview?

Let's look at how to limit characters (easy with limitations) and whole words (more involved but better control and end user experience).

By Characters: Substring()

The first and easiest solution is to use the Substring() function, which allows you to designate a starting position and a number of characters to show. For example, this would create a new @preview_text variable with the first (starting from position 1) 100 characters in a longer @full_length_text variable.

set @preview_text = Substring(@full_length_text,1,100)

Enter fullscreen mode Exit fullscreen mode

This is a really powerful function when you know exactly what character position you want to start and how many characters you want. However, it can lead to unexpected results because you have limited control over where things break.

As a real-world example, here is how I set up the subject line for a back-in-stock alert email, adding the first 30 characters of the product name:

set @subject_line = Concat('Back In Stock: ',Substring(@product_name,1,30),'...')

Enter fullscreen mode Exit fullscreen mode

Simple enough — a product name of "Totally Fake Awesome Product Name" will appear as:
Back In Stock: Totally Fake Awesome Product N...

But you don't know where that will break, including in the middle of a word. One day while testing an update and reviewing emails sent to real customers, I did a double-take on this one:
Back In Stock: Polaris Full Coverage Rear Bum...

Not the greatest place for the text to cut — suddenly a protective bumper for an off-road vehicle (Polaris Full Coverage Rear Bumper) sounds a little... inappropriate. That was when I knew I had to switch to whole words.


By Words: BuildRowsetFromString() And A for Loop

This is a bit more involved but insures that everything is checked in whole words. We'll do two versions:

  • Allowing X words, regardless of character length

  • Allowing whole words up to X total characters

I originally applied this to my subject line example above, but let's use some classic Lorem Ipsum text to show it on a larger scale (for example, if you were including an article preview in an email).

Allowing X Words

The first thing we'll do is break down our full-length text into individual words with the BuildRowsetFromString() function, splitting on spaces.

set @full_length_text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'

set @words_rowset = BuildRowsetFromString(@full_length_text," ")

Enter fullscreen mode Exit fullscreen mode

This breaks a single string of text...
Lorem ipsum dolor sit amet...

...into a rowset, where each word is now a single field in its own row.

Lorem
ipsum
dolor
sit
amet
...

Enter fullscreen mode Exit fullscreen mode

Second, we'll determine how many words we want to include.

set @allowed_words = 20

Enter fullscreen mode Exit fullscreen mode

Third, we'll start a for loop to iterate through the first X words (based on @allowed_words) and Concat() them back together with spaces.

/* Set an empty variable that will be filled by the 'for' loop. */
set @short_text = ''

/* Start a 'for' loop, which iterates (@i) from the 1st word to the number of allowed words, and 'do' steps for each. */
for @i = 1 to @allowed_words do

    /* Lock into each row. */
    set @i_words_row = Row(@words_rowset,@i)

    /* Get the 1st (and only) field in each row, which is a single word. */
    set @i_word = Field(@i_words_row,1)

    /* Add the current word to the short text variable, including a space. */
    set @short_text = Concat(@short_text,@i_word,' ')
next @i

Enter fullscreen mode Exit fullscreen mode

At this point, we would have...
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut

...20 words with a space after each, including after the last word.

Let's do some quick cleanup, starting with removing the trailing space with the Trim() function.

/* Remove any trailing spaces. */
set @short_text = Trim(@short_text)

Enter fullscreen mode Exit fullscreen mode

Another thing I like to avoid is punctuation at the end. Since we're defining words as separated by spaces:

  • A word followed by a comma includes the comma in the word, and we don't want ",..." at the end.

  • Standalone punctuation commonly separated by spaces would also be treated as words, including ampersands & and all forms of hyphens and dashes.

To clean that up, we'll use Substring() to select the last character of the text, and compare it to a list of punctuation marks with IndexOf() (AMPscript's best "contains" function). If it matches, then we'll use Substring() one more time to trim/remove the last character.

(If you wanted, you could use the RegExMatch() function to get really advanced on this check, but a simple list of punctuation has been sufficient in my experience.)

/* Select the last character, and if it's punctuation, remove it. */
set @last_character = Substring(@short_text,Length(@short_text),1)

if IndexOf('-–—,;:&+/\',@last_character) != 0 then
    set @short_text = Substring(@short_text,1,Subtract(Length(@short_text),1))
endif

Enter fullscreen mode Exit fullscreen mode

Finally, we'll add an ellipsis ... if the total word count is greater than the allowed word count.

/* If the original phrase had more words than allowed, then add an ellipsis at the end. */
if RowCount(@words_rowset) > @allowed_words then
    set @short_text = Concat(@short_text,'...')
endif

Enter fullscreen mode Exit fullscreen mode

Our original text has significantly more than 20 words, so with cleanup, it displays as:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut...

If the text had fewer words than allowed, no trimming would be done and the entire thing would be displayed.

Here is the complete ready-to-copy/paste code — just set your own value for @full_length_text and determine the @allowed_words count.

set @full_length_text = 'Any text or variable name you want'

/* Break down the full text into individual words split by spaces. */
set @words_rowset = BuildRowsetFromString(@full_length_text," ")

/* Decide how many words should be included. */
set @allowed_words = 20

/* Set an empty variable that will be filled by the 'for' loop. */
set @short_text = ''

/* Start a 'for' loop, which iterates (@i) from the 1st word to the number of allowed words, and 'do' steps for each. */
for @i = 1 to @allowed_words do

    /* Lock into each row. */
    set @i_words_row = Row(@words_rowset,@i)

    /* Get the 1st (and only) field in each row, which is a single word. */
    set @i_word = Field(@i_words_row,1)

    /* Add the current word to the short text variable, including a space. */
    set @short_text = Concat(@short_text,@i_word,' ')
next @i

/* Remove any trailing spaces. */
set @short_text = Trim(@short_text)

/* Select the last character, and if it's punctuation, remove it. */
set @last_character = Substring(@short_text,Length(@short_text),1)

if IndexOf('-–—,;:&+/\',@last_character) != 0 then
    set @short_text = Substring(@short_text,1,Subtract(Length(@short_text),1))
endif

/* If the original phrase had more words than allowed, then add an ellipsis at the end. */
if RowCount(@words_rowset) > @allowed_words then
    set @short_text = Concat(@short_text,'...')
endif

Enter fullscreen mode Exit fullscreen mode


Allowing Words Up To X Characters

Obviously not all words are the same length, so this can still vary quite a bit with longer vs. shorter words. Let's look at another variant that doesn't allow a specific number of words, but allows words until a specific number of total characters is reached.

There are some key differences here:

  • Instead of setting a count of @allowed_words, it sets @allowed_characters.

  • When starting the for loop, it iterates through all words, using RowCount(@words_rowset) instead of @allowed_words to control the number of iterations.

  • Within the for loop, there is an additional if check comparing the word's character count and the character count so far, to see if adding the next word will exceed the max character count.

  • The ellipsis check looks at the character count of the original full-length text instead of the number of words.

set @full_length_text = 'Any text or variable name you want'

/* Break down the full text into individual words split by spaces. */
set @words_rowset = BuildRowsetFromString(@full_length_text," ")

/* Decide how many characters should be allowed. */
set @allowed_characters = 150

/* Set an empty variable that will be filled by the 'for' loop. */
set @short_text = ''

/* Start a 'for' loop, which iterates (@i) from the 1st word to the number of total words, and 'do' steps for each. */
for @i = 1 to RowCount(@words_rowset) do

    /* Lock into each row. */
    set @i_words_row = Row(@words_rowset,@i)

    /* Get the 1st (and only) field in each row, which is a single word. */
    set @i_word = Field(@i_words_row,1)

    /* If adding the current word to the short text (so far) will not exceed the allowed number of characters, then add it. */
    if Add(Length(@i_word),Length(@short_text)) < @allowed_characters then

        /* Add the current word to the short text variable, including a space. */
        set @short_text = Concat(@short_text,@i_word,' ')

    endif

next @i

/* Remove any trailing spaces. */
set @short_text = Trim(@short_text)

/* Select the last character, and if it's punctuation, remove it. */
set @last_character = Substring(@short_text,Length(@short_text),1)

if IndexOf('-–—,;:&+/\',@last_character) != 0 then
    set @short_text = Substring(@short_text,1,Subtract(Length(@short_text),1))
endif

/* If the original phrase had more characters than allowed, then add an ellipsis at the end. */
if Length(@full_length_text) > @allowed_characters then
    set @short_text = Concat(@short_text,'...')
endif

Enter fullscreen mode Exit fullscreen mode

Going back to our Lorem Ipsum example, when set to allow up to 150 characters, it cuts after "...veniam,".

  • The existing @short_text up to that point is at 149 characters, including the last space.

  • Adding 4 more characters for "quis" would be a total of 153, exceeding the 150 character limit, so "quis" and all following words are skipped.

  • Our punctuation check trims off the comma.

  • And finally we see: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam...


If you have additional use cases or limitations not covered here — or want to share your own examples of trimmed text gone wrong — drop me a comment!