- Why Choose StringKit-FP?
- Feature Overview
- Installation (Lazarus IDE)
- Manual Installation (General)
- Usage
- Start Weaving: Quick Thread Patterns
- System Requirements
- Documentation
- Testing
- License
- Changelog
Professional string toolkit featuring advanced algorithms: Levenshtein/Jaro similarity, Soundex/Metaphone phonetics, readability scoring, regex patterns, HTML/URL encoding, and comprehensive validation. Static API, no instantiation required.
π― Key Advantages:
- π§Ά Comprehensive: 90+ string operations covering validation, transformation, analysis, and encoding
- πͺ‘ Zero Dependencies: Uses only standard Free Pascal RTL - no external libraries required
- π Advanced Analysis: Readability scoring, n-gram generation, and statistical text analysis
- π Robust Validation: Regex patterns, format checking, and custom validation rules
- π Web-Ready: URL encoding, HTML escaping, and modern web standards support
- π§ͺ Thoroughly Tested: Comprehensive test suite ensuring reliability in production
- β‘ Simple API: Static methods - no object instantiation required, just call and use
Professional text styling and formatting
ToUpper()
,ToLower()
,ToTitleCase()
- Standard case transformationsToCamelCase()
,ToPascalCase()
,ToSnakeCase()
,ToKebabCase()
- Modern naming conventionsPadLeft()
,PadRight()
,PadCenter()
- Text alignment with custom paddingTruncate()
- Smart text truncation with ellipsis supportCapitalizeText()
- Intelligent word capitalization
Robust string validation and pattern extraction
IsValidEmail()
,IsValidURL()
,IsValidIP()
- Comprehensive format validationIsValidDate()
- Date validation with custom format supportMatchesPattern()
- Powerful regex pattern matchingExtractMatches()
,ExtractAllMatches()
- Extract matching substrings
Advanced string comparison algorithms
LevenshteinDistance()
,LevenshteinSimilarity()
- Edit distance calculationsHammingDistance()
- Character-by-character comparison for equal-length stringsJaroSimilarity()
,JaroWinklerSimilarity()
- Sophisticated similarity metricsLongestCommonSubsequence()
,LCSSimilarity()
- Common subsequence analysisIsFuzzyMatch()
- Multi-algorithm fuzzy string matching
Sound-based string comparison algorithms
Soundex()
- Russell-Odell phonetic algorithm for name matchingMetaphone()
- Advanced English pronunciation-based matching
Professional number and numeric string handling
ToRoman()
,FromRoman()
- Roman numeral conversion (1-3999)FormatFileSize()
- Human-readable file size formatting (B, KB, MB, GB, TB)FormatNumber()
,FormatFloat()
- Thousand-separator formattingToOrdinal()
- Ordinal number formatting (1st, 2nd, 3rd...)NumberToWords()
- Convert numbers to English words
Web-safe string encoding and decoding
HTMLEncode()
,HTMLDecode()
- HTML entity encoding for safe web outputURLEncode()
,URLDecode()
- URL parameter encoding/decodingHexEncode()
,HexDecode()
- Hexadecimal string conversion
Statistical analysis and text insights
CountWords()
,GetWords()
- Word counting and extractionFleschKincaidReadability()
- Readability scoring for content assessmentGenerateNGrams()
- N-gram generation for linguistic analysis
Essential string manipulation operations
Split()
,Join()
- String splitting and joining operationsReplaceText()
,ReplaceRegEx()
- Text replacement with regex supportContains()
,StartsWith()
,EndsWith()
- String content inspectionCollapseWhitespace()
,RemoveWhitespace()
- Whitespace normalizationDuplicateText()
,ReverseText()
- String duplication and reversalGetLength()
,SubString()
,LeftStr()
,RightStr()
- String length and extractionCountSubString()
- Substring occurrence counting
Quick setup for Lazarus development
- Clone the repository:
git clone https://github.com/ikelaiah/stringkit-fp
-
Open your project - Open/start a new project in Lazarus IDE
-
Add the package - Go to
Package
βOpen Package File (.lpk)...
-
Select the package - Navigate to the StringKit packages in the
packages/lazarus/
folder and selectstringkit_fp.lpk
-
Compile the package - In the package window that opens, click
Compile
-
Install to project - Click
Use β Add to Project
to install the package
β Installation complete! StringKit is now available in your Lazarus project.
Alternative setup method
- Clone the repository:
git clone https://github.com/ikelaiah/stringkit-fp
- Configure your project - Add the source directory to your project's search path.
Import StringKit into your project
uses
// String manipulation library
StringKit; // All string operations
Minimal end-to-end usage with static and helper APIs:
uses
SysUtils,
StringKit,
StringKitHelper; // enable instance-style helper
begin
// Validation (helper)
if 'user@example.com'.IsValidEmail then
WriteLn('Valid email');
// Formatting (static)
WriteLn(TStringKit.FormatFileSize(1048576)); // 1.00 MB
// Encoding (helper)
WriteLn('foo'.Encode64); // Zm9v
end.
StringKit also provides a string type helper for more natural, instance-style calls.
uses
StringKit, StringKitHelper; // Enable helper-backed instance methods on 'string'
var
S: string;
begin
// Instance-style calls (via TStringHelperEx)
S := ' hello world '.Trim; // 'hello world'
S := 'Hello World'.ToSnakeCase; // 'hello_world'
if 'user@example.com'.IsValidEmail then ; // True
S := 'Hello World!'.URLEncode; // 'Hello+World%21'
S := 'foo'.Encode64; // 'Zm9v'
// Equivalent static calls still work
S := TStringKit.Trim(' hello world ');
end;
Notes:
- Add
StringKitHelper
to your unit'suses
clause to enable helper methods. - Most
TStringKit
string-first methods are available via the helper for convenience; methods that don't operate on a source string may remain as static calls.
As of 1.6.0, TStringHelperEx
is modularized using conditional includes to let you select which groups compile into the helper.
- Default: if no symbols are defined,
SK_ALL
enables all groups. - Selective mode: define
SK_ANY
and then enable specific groups you need.
Available groups:
SK_MANIP
β trim, pad, collapse whitespace, reverse, length, substringSK_MATCH
β regex match/extract, contains/starts/ends, words, countsSK_COMPARE
β Levenshtein, Hamming, Jaro/Jaro-Winkler, LCS, fuzzySK_CASE
β title, camel, pascal, snake, kebabSK_VALIDATE
β email, URL, IP (v4/v6), dateSK_FORMAT
β truncate, file size, number/float formattingSK_NUMERIC
β roman, ordinal, number-to-words, from-romanSK_ENCODE
β hex, base64, HTML, URL encode/decodeSK_SPLIT
β split, joinSK_PHONETIC
β soundex, metaphone, readability, ngrams, basic counts
Notes:
- Implementation and interface includes live under
src/inc/
and are pulled fromsrc/StringKitHelper.pas
using{$I ...}
. - When
SK_ALL
(default) is active, the helper API matches the full surface as before. - See also: CHANGELOG 1.6.0 for the summary.
Enable only encoding/decoding helpers via feature flags, then use StringKitHelper
without static calls.
- Lazarus (FPC): Project Options > Compiler Options > Custom Options
-dSK_ANY -dSK_ENCODE
Uses:
uses SysUtils, StringKitHelper;
Examples:
begin
// 1) Base64
WriteLn('foo'.Encode64); // Zm9v
WriteLn('Zm9v'.Decode64); // foo
// 2) URL
WriteLn('Hello World!'.URLEncode); // Hello+World%21
WriteLn('Hello+World%21'.URLDecode); // Hello World!
// 3) HTML
WriteLn('<b>Hi</b>'.HTMLEncode); // <b>Hi</b>
WriteLn('<b>Hi</b>'.HTMLDecode); // <b>Hi</b>
// 4) Hex
WriteLn('abc'.HexEncode); // 616263
WriteLn('616263'.HexDecode); // abc
// 5) Chaining (HTML then URL)
WriteLn('<p class="x">'.HTMLEncode.URLEncode);
end.
Note on defines scope:
{$DEFINE ...}
inside your program controls conditional blocks in your program only. It does not affect howsrc/StringKitHelper.pas
is compiled in a separate unit.- To actually compile the helper with only
SK_ENCODE
, set defines at the project/build level so the compiler sees them when compilingStringKitHelper.pas
:- Lazarus/FPC: Project Options > Compiler Options > Custom Options β
-dSK_ANY -dSK_ENCODE
- Lazarus/FPC: Project Options > Compiler Options > Custom Options β
Transform your raw strings into beautifully styled threads
var
Text: string;
begin
// Case conversions
Text := TStringKit.ToCamelCase('hello world'); // Returns: 'helloWorld'
Text := TStringKit.ToPascalCase('hello world'); // Returns: 'HelloWorld'
Text := TStringKit.ToSnakeCase('HelloWorld'); // Returns: 'hello_world'
Text := TStringKit.ToKebabCase('HelloWorld'); // Returns: 'hello-world'
Text := TStringKit.ToTitleCase('hello world'); // Returns: 'Hello World'
// Padding and formatting
Text := TStringKit.PadLeft('123', 8, '0'); // Returns: '00000123'
Text := TStringKit.PadRight('Name', 10, '.'); // Returns: 'Name......'
Text := TStringKit.PadCenter('Hi', 10, '-'); // Returns: '----Hi----'
Text := TStringKit.Truncate('Very long text', 10); // Returns: 'Very lo...'
Text := TStringKit.CapitalizeText('hello world'); // Returns: 'Hello World'
end;
Inspect your threads and extract beautiful patterns
var
Matches: TMatchesResults;
AllMatches: TStringDynArray;
i: Integer;
begin
// Built-in validators
if TStringKit.IsValidEmail('user@example.com') then
WriteLn('Valid email');
if TStringKit.IsValidURL('https://example.com') then
WriteLn('Valid URL');
if TStringKit.IsValidIPv4('192.168.1.1') then
WriteLn('Valid IPv4');
if TStringKit.IsValidDate('2023-12-25', 'yyyy-mm-dd') then
WriteLn('Valid date');
// Pattern matching and extraction
if TStringKit.MatchesPattern('ABC123', '^[A-Z]{3}\d{3}$') then
WriteLn('Matches pattern');
// Extract all matches with position info
Matches := TStringKit.ExtractMatches('Call 555-1234 or 555-5678', '\d{3}-\d{4}');
for i := 0 to High(Matches) do
WriteLn(Format('Found: %s at position %d', [Matches[i].Text, Matches[i].Position]));
// Extract just the matched text
AllMatches := TStringKit.ExtractAllMatches('Emails: a@b.com, c@d.net', '\w+@\w+\.\w+');
for i := 0 to High(AllMatches) do
WriteLn('Email: ' + AllMatches[i]);
end;
Compare and measure the likeness between different thread types
var
Distance: Integer;
Similarity: Double;
begin
// String distance algorithms
Distance := TStringKit.LevenshteinDistance('kitten', 'sitting'); // Returns: 3
Distance := TStringKit.HammingDistance('karolin', 'kathrin'); // Returns: 3
// Similarity ratios (0.0 to 1.0)
Similarity := TStringKit.LevenshteinSimilarity('test', 'best'); // Returns: ~0.75
Similarity := TStringKit.JaroSimilarity('MARTHA', 'MARHTA'); // Returns: ~0.94
Similarity := TStringKit.JaroWinklerSimilarity('MARTHA', 'MARHTA'); // Higher than Jaro
// Fuzzy matching with threshold
if TStringKit.IsFuzzyMatch('apple', 'appel', 0.8) then
WriteLn('Close match found');
// Longest common subsequence
WriteLn(TStringKit.LongestCommonSubsequence('ABCDEFG', 'ABDZEFXG')); // Returns: 'ABDEG'
end;
Match threads by their sonic fingerprint
var
Code1, Code2: string;
begin
// Soundex for name matching
Code1 := TStringKit.Soundex('Robert'); // Returns: 'R163'
Code2 := TStringKit.Soundex('Rupert'); // Returns: 'R163'
if Code1 = Code2 then
WriteLn('Names sound similar');
// Metaphone for pronunciation
Code1 := TStringKit.Metaphone('knight'); // Returns: 'NT'
Code2 := TStringKit.Metaphone('night'); // Returns: 'NT'
if Code1 = Code2 then
WriteLn('Words sound the same');
end;
Spin numbers into elegant, readable thread patterns
var
Roman: string;
Number: Integer;
Formatted: string;
begin
// Roman numerals
Roman := TStringKit.ToRoman(1994); // Returns: 'MCMXCIV'
Number := TStringKit.FromRoman('MCMXCIV'); // Returns: 1994
// File size formatting
Formatted := TStringKit.FormatFileSize(1048576); // Returns: '1.00 MB'
Formatted := TStringKit.FormatFileSize(1500000000); // Returns: '1.40 GB'
// Number formatting
Formatted := TStringKit.FormatNumber(1234567); // Returns: '1,234,567'
Formatted := TStringKit.FormatFloat(12345.67, 2); // Returns: '12,345.67'
Formatted := TStringKit.FormatFloat(1234.5, 3, ',', '.'); // Returns: '1.234,500'
// Ordinal and word conversion
Formatted := TStringKit.ToOrdinal(21); // Returns: '21st'
Formatted := TStringKit.NumberToWords(123); // Returns: 'one hundred and twenty-three'
end;
Ready your threads for the digital tapestry of the web
var
Encoded, Decoded: string;
begin
// HTML encoding for safe web content
Encoded := TStringKit.HTMLEncode('<p class="bold">Text</p>');
// Returns: '<p class="bold">Text</p>'
Decoded := TStringKit.HTMLDecode('<p>Hello & World</p>');
// Returns: '<p>Hello & World</p>'
// URL encoding for web parameters
Encoded := TStringKit.URLEncode('Hello World!'); // Returns: 'Hello+World%21'
Decoded := TStringKit.URLDecode('Hello+World%21'); // Returns: 'Hello World!'
// Base64 encoding/decoding
Encoded := TStringKit.Encode64('foo'); // Returns: 'Zm9v'
Decoded := TStringKit.Decode64('Zm8='); // Returns: 'fo'
// Hexadecimal encoding
Encoded := TStringKit.HexEncode('Hello'); // Returns: '48656C6C6F'
Decoded := TStringKit.HexDecode('48656C6C6F'); // Returns: 'Hello'
end;
Examine your woven text like a master craftsperson
var
WordCount: Integer;
Readability: Double;
NGrams: TStringDynArray;
i: Integer;
begin
// Basic text statistics
WordCount := TStringKit.CountWords('Hello, world! How are you?'); // Returns: 5
// Readability scoring (0-100, higher = easier)
Readability := TStringKit.FleschKincaidReadability('The quick brown fox jumps.');
WriteLn(Format('Readability score: %.1f', [Readability]));
// N-gram generation for NLP
NGrams := TStringKit.GenerateNGrams('the quick brown fox', 2); // Bigrams
for i := 0 to High(NGrams) do
WriteLn('Bigram: ' + NGrams[i]);
// Output: 'the quick', 'quick brown', 'brown fox'
end;
The fundamental techniques every string artisan must know
var
Parts: TStringDynArray;
Joined: string;
i: Integer;
begin
// Splitting and joining
Parts := TStringKit.Split('apple,banana,cherry', ',');
for i := 0 to High(Parts) do
WriteLn('Part: ' + Parts[i]);
Joined := TStringKit.Join(Parts, ' | '); // Returns: 'apple | banana | cherry'
// Text replacement
Joined := TStringKit.ReplaceText('Hello World', 'World', 'Pascal');
// Returns: 'Hello Pascal'
Joined := TStringKit.ReplaceRegEx('Phone: 123-456-7890', '(\d{3})-(\d{3})-(\d{4})', '($1) $2-$3');
// Returns: 'Phone: (123) 456-7890'
// String testing
if TStringKit.StartsWith('Hello World', 'Hello') then
WriteLn('Starts with Hello');
if TStringKit.EndsWith('test.txt', '.txt') then
WriteLn('Is a text file');
if TStringKit.Contains('Hello World', 'World') then
WriteLn('Contains World');
// Text cleaning
Joined := TStringKit.CollapseWhitespace(' Multiple spaces '); // Returns: ' Multiple spaces '
Joined := TStringKit.RemoveWhitespace(' No spaces '); // Returns: 'Nospaces'
// String extraction and manipulation
Joined := TStringKit.LeftStr('Hello World', 5); // Returns: 'Hello'
Joined := TStringKit.RightStr('Hello World', 5); // Returns: 'World'
Joined := TStringKit.SubString('Hello World', 7, 5); // Returns: 'World'
Joined := TStringKit.DuplicateText('Hi! ', 3); // Returns: 'Hi! Hi! Hi! '
// String analysis
WriteLn(TStringKit.GetLength('Hello')); // Returns: 5
WriteLn(TStringKit.CountSubString('ababab', 'ab')); // Returns: 3
end;
Module | Windows 11 | Ubuntu 24.04.2 |
---|---|---|
StringKit | β | β |
- Windows
- No external dependencies required
- Linux
- No external dependencies required
- Uses only standard Free Pascal RTL units
- Free Pascal Compiler (FPC) 3.2.2+
- Lazarus 4.0+
- Basic development tools (git, terminal, etc)
For detailed documentation, see:
- π Cheat Sheet
- π StringKit Helper Coverage
- Open the
TestRunner.lpi
using Lazarus IDE - Compile the project
- Run the Test Runner:
$ cd tests
$ ./TestRunner.exe -a --format=plain
Our roadmap for expanding the string artisan's toolkit
- Remove custom types and use RTL types
- Introduce custom method for hashing
- Enhance multi-byte character weaving for global text tapestries
- Seamless support for Free Pascal and Lazarus package managers
Every master weaver started as an apprentice - your contributions help strengthen our tapestry!
Contributions are warmly welcomed! Whether you're adding new thread patterns, fixing loose ends, or improving our weaving techniques, please feel free to submit a Pull Request. For major pattern changes, please open an issue first to discuss your vision.
- Fork the Loom - Fork the Project
- Create your Pattern - Create your Feature Branch (
git checkout -b feature/AmazingThreadPattern
) - Weave your Changes - Commit your Changes (
git commit -m 'Add beautiful new thread pattern'
) - Share your Work - Push to the Branch (
git push origin feature/AmazingThreadPattern
) - Present to the Guild - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Standing on the shoulders of giants who wove the foundation
- ποΈ The FPC Guild - For crafting the magnificent Free Pascal loom
- π§΅ Fellow Weavers - All contributors and maintainers who help strengthen our tapestry
- π¨ String Artisans Everywhere - The community that inspires continuous innovation
π§Ά Ready to start weaving? Your feedback helps us craft better tools! Visit our thread workshop to share ideas, report loose threads, or track our weaving progress.
β¨ Happy String Weaving! β¨
"In every thread lies infinite possibility, in every string a story waiting to be told."