# Overview

The Strings package is an evolution of work originally produced by Andrew Mezoni.

The purpose of the Strings package is to provide:

* A collection of useful String functions to complement to the core String class.
* where viable, directly extend the String class with methods such as String.right, String.left.
* provide a safer environment when working with nullable Strings (String?)
* wrappers for each of the core String methods which are safe to use with a nullable String?.

A core objective of the Strings package is to never 'throw' or return an error but to make a best effort to process the passed data.

```dart
// pass a short string and we can pad it (or not).
Strings.right('one', 4, pad: Pad.left);
 -> ' one'

// passing null works too.
Strings.right(null, 4, pad: Pad.left);
 -> '    '
```

## Sponsored by OnePub <a href="#sponsored-by-onepub" id="sponsored-by-onepub"></a>

Help support Strings by supporting [OnePub](https://onepub.dev/drive/b37ef958-bdc9-49bc-af7b-d31f1dd7c65d), the private Dart repository.

OnePub allows you to privately share Dart packages across your Team and with your customers.

Try it for free and publish your first private package in seconds.

| ![](https://1656630654-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FwUAsvt8f6XkYPVxtypLs%2Fuploads%2FoHUYIEJIYYd9Ia330arT%2Fimage.png?alt=media\&token=78a7002f-44c2-4c92-84da-841c0f972554)![](broken://files/rc2pt36Jck9po23ILnYz) | <p>Publish a private package in five commands:</p><p><mark style="color:green;"><code>flutter pub global activate onepub</code></mark></p><p><mark style="color:green;"><code>onepub login</code></mark><br><mark style="color:green;">cd \<my package></mark><br><mark style="color:green;">onepub pub private</mark><br><mark style="color:green;">dart pub publish</mark></p> |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

## namespace

Strings takes a slightly non-conventional approach by defining all of the exposed methods as statics in the Strings class rather than defining them as global functions.

We took this approach as it provides better support when using auto-completion in an IDE.

Can't remember the name of a Strings function?

Type `Strings.` and your IDE will show you the complete list of methods exposed by the Strings package.

To use a Strings method use Strings.xxxx

```dart
Strings.abbreviate('A long sentence that goes on forever', 10);
-> 'A long ...'
```

## NNBD

Dart best practice encourages us to use String rather than String? but the reality is that at times we still need to handle nullable strings.

The Strings package looks to make using String? types as easy as possible whilst reducing bugs and maintenance overheads.

If you need to trim a String? you could write:

```dart
value!.trim();
or
(value ?? '').trim();
or 
value == null ? value.trim() : '';
```

or use Strings  and write:

```dart
Strings.trim(value);
```

The null check operator (!) is dangerous, because if the value is null then our app just crashed.

The Strings method is slightly less verbose than the '??' technique, but more importantly it removes the need for the conditional expression which is both hard to read and like every conditional expression, has the potential to introduce bugs into your code base.

## Utility methods

The methods in the  Strings package is loosely group into the following types:

* [Blank](/blank) - test if a string is blank

```dart
bool isBlank(String? value)
bool isNotBlank(String? value) 
```

* [Empty](/empty) - test if a string is empty

```dart
bool isEmpty(String? string) 
bool isNotEmpty(String? string)
String orElse(String? string, String elseValue) 
String orElseCall(String? string, String Function() elseValue) 
String toEmpty(String? string)
```

* [Parts](/parts) - break/merge a string into parts

```dart
String abbreviate(String? string, int maxWidth, {int offset = 0})
String join(List<Object?>? list, {String separator = ''})
 String hidePart(String? string,
      {int start = 0, int? end, String replaceWith = '*'}) 
String left(String? string, int take, {Pad pad = Pad.none})
String right(String? string, int take, {Pad pad = Pad.none})
```

* [Style](/style) - style a string with different cases etc

```dart
bool isLowerCase(String? string) 
bool isPrintable(int? character)
bool isUpperCase(String? string)
bool startsWithLowerCase(String? string)
bool startsWithUpperCase(String? string) 
String toCamelCase(String? string, {bool lower = false})
String toCapitalised(String? string)
String toProperCase(String? sentence) 
String toSnakeCase(String? string) 
```

* [Transformations](/transform)

```dart
String reverse(String? string)
String toEscape(String? string,
      {String Function(int charCode)? encode})
String toPrintable(String? string)
String toUnicode(int? charCode) 
```

* [Type](/type) - check if a string is a given type

```dart
bool isNumeric(String? string)
bool isAscii(String? string)
```

## Extensions to String

The Strings package also provides a set of extension  functions for the String class:

```dart
import 'package:strings/strings.dart';
'a normal string'.left(1);
-> 'a'
```

```dart
String abbreviate(int maxWidth, {int offset = 0})
bool equalsIgnoreCase(String? rhs)
String hidePart(String? string,
      {int start = 0, int? end, String replaceWith = '*'}) 
bool isAscii()
bool isBlank()
bool isNotBlank()
bool isLowerCase() 
bool isNumeric()
bool isUpperCase()
String left(int take, {Pad pad = Pad.none})
String reverse()
String right(int take, {Pad pad = Pad.none})
bool startsWithLowerCase()
bool startsWithUpperCase() 
String toCamelCase({bool lower = false})
String toCapitalised()
String toPrintable()
String toProperCase() 
String toSnakeCase() 
```

## Contributing

We welcome contributions to the Strings package.

The best way to get involved is to head over to the Strings github repository and fork the project.

If you are looking to add a new method please conform to the current code layout.

### Unit Tests

Before any new functions are added to the library they need reasonable set of unit tests.


# Blank

## Testing for blank

A blank String is a String that is meets at least one of the following criteria:

* null
* zero length
* only contains whitespace

### isBlank

```dart
 String isBlank(String? string)
```

The isBlank returns true if ANY ONE of the above criteria holds true

```dart
String.isBlank(null);
-> true
String.isBlank('');
-> true
String.isBlank('\t\n\r ');
-> true
String.isBlank('a');
-> false
```

### isNotBlank

```dart
 String isNotBlank(String? string)
```

The isNotBlank returns true only if ALL  of the above criteria are invalid

```dart
String.isNotBlank(null);
-> false
String.isNotBlank('');
-> false
String.isNotBlank('\t\n\r ');
-> flase
String.isNotBlank('a');
-> true
```


# Empty

## Testing for an Empty String

An Empty String is a String that is meats at least ONE of the following criteria

* is null
* is zero length

### isEmpty

```dart
 String isEmpty(String? string)
```

The isEmpty returns true if ANY ONE of the above criteria holds true

```dart
String.isEmpty(null);
-> true
String.isEmpty('');
-> true
String.isEmpty('\t\n\r ');
-> false
String.isEmpty('a');
-> false
```

### isNotEmpty

```dart
 String isNotEmpty(String? string)
```

The isNotBlank returns true only if ALL  of the above criteria are invalid

```dart
String.isNotEmpty(null);
-> false
String.isNotEmpty('');
-> false
String.isNotEmpty('\t\n\r ');
-> true
String.isNotEmpty('a');
-> true

```


# Parts

## Processing parts of a String

Strings allow you to work with parts of a String, splitting or joining a string.

### abbreviate

```dart
 String abbreviate(String? string, int maxWidth, {int offset = 0})
```

The abbreviate method truncates a string to 'maxWidth' characters and adds '...' to the end.

```dart
String.abbreviate("A long Sentence", 9);
-> A long...
```

The maxWidth argument sets the maxWidth of the resulting String, including the trailing ellipsis (...).

You can use the 'offset' argument to control where the truncation starts from.

<pre class="language-dart"><code class="lang-dart"><strong>String.abbreviate("A long Sentence", 9, offset: 3);
</strong>-> A long Se...
</code></pre>

If the 'string' is shorter than 'maxWidth' then the string is returned without change.

If you pass null then 'string' will be treated as a zero length string.

<pre class="language-dart"><code class="lang-dart"><strong>String.abbreviate(null, 9);
</strong><strong>-> ''
</strong></code></pre>

#### Extension

The `abbreviate` method is available as an extension method on the String class.

```dart
'abcdef'.abbreviate(5);
-> 'ab...'
```

## hidePart

```dart
static String hidePart(String? string,
      {int start = 0, int? end, String replaceWith = '*'})
```

The 'hidePart' method replaces a section of the string with replacement character.

This can be used to hide a security token or a password contained within a string.

To hide a section of the string define a `start` position (defaults to 0) and an `end` position (defaults to the end of the string). The `start` position is inclusive and the `end` exclusive (just like substring).

Be default the replacement string is '\*' but you can modify the value by passing an alternate string to `replaceWith`. `replaceWith` is normally a single character but it can be any String.

```dart
Strings.hidePart('my password', start: 3, replaceWith: '#');
-> 'my ########'
```

#### extension

The `hidePart` method is available as an extension method on the String class;

```
'my password'.hidePart(start: 0, end: 2, replaceWith: 'x');
-> 'xx password'
```

## join

```dart
  static String join(List<Object?>? list, {String separator = ''}) 
```

The 'join' method concatenates a list of objects into a String by calling their 'toString' method, separating each item with the separator.

If the 'list' is null an empty String is returned;

If any member of the list is null then just the separator is output for that element.

```dart
Strings.join(['a', 'b', null, 'c'], separator, ',')
-> 'a,b,,c';
```

### left

```dart
  static String left(String? string, int length, {Pad pad = Pad.none})
```

The left method returns the left 'n' characters from a string.

<pre class="language-dart"><code class="lang-dart"><strong>Strings.left('one', 1);
</strong><strong> -> 'o'
</strong></code></pre>

If the String is less than the 'length' passed then you can optionally pad the String to 'length' characters long.

```dart
Strings.left('one', 4, pad: Pad.left);
-> ' one'
Strings.left('one', 4, pad: Pad.right);
-> 'one '
```

By default, no padding will be applied (Pad.none).

```dart
Strings.left('one', 4);
-> 'one'
```

If you pass null then it will be treated as a zero length String.

```dart
Strings.left(null, 4, pad: Pad.left);
-> '    '
```

#### extension

The 'left' method is available as an extension method on the String class.

```dart
'hello world'.left(5);
-> hello
```

### right

```dart
  static String right(String? string, int length, {Pad pad = Pad.none})
```

The right method returns the right 'n' characters from a string.

<pre class="language-dart"><code class="lang-dart"><strong>Strings.right('one', 1);
</strong><strong> -> 'e'
</strong></code></pre>

If the String is less than the 'length' passed then you can optionally pad the String to 'length' characters long.

```dart
Strings.right('one', 4, pad: Pad.left);
-> ' one'
Strings.right('one', 4, pad: Pad.right);
-> 'one '
```

By default, no padding will be applied (Pad.none).

```dart
Strings.right('one', 4);
-> 'one'
```

If you pass null then it will be treated as a zero length String.

```dart
Strings.right(null, 4, pad: Pad.left);
-> '    '
```

#### extension

The 'right' method is available as an extension method on the String class.

```dart
'hello world'.right(5);
-> world
```


# Safe

The Strings package provides null safe wrappers for each of the String methods.

Generally, the Safe methods convert a null String? to an empty String before passing the string to the wrapped String method.

In some cases we do additional processing to avoid RangeExceptions and other problems caused by an empty String. These exceptions are noted below.

## length

Refer to String.length

```dart
Strings.length('abc');
-> 3
Strings.length(null);
-> 0
```

## codeUnits

Refer to String.codeUnits

```dart
Strings.codeUnits('abc')
-> [0xxx, 0xyy, 0xzz]
Strings.codeUnits(null)
-> []
```

## runes

Refer to String.runes

```dart
Strings.runes('abc')
-> list of runes
Strings.runes(null)
-> []
```

## compareTo

```dart
  static int compareTo(String? string, String? other,
      {bool nullIsLessThan = true})
```

The compareTo method returns two Strings returning 1, 0 or -1.

If both `string` and `other` are null then -1 is returned.

If one of `string` and `other` are null then -1 or \` is returned based on 'nullIsLessThan'.

If nullIsLessThan is true than null is treated as less than all other strings.

If nullIsLessThan is false then null is treated as greater than all other strings.

## contains

Refer to String.contains

```dart
Strings.contains('abc', 'ab')
-> true
Strings.contains(null, 'ab')
-> false
```

## endsWith

Refer to String.endsWith

```dart
Strings.endsWith('abc', 'bc')
-> true
Strings.endsWith(null, 'ab')
-> false
```

## indexOf

Refer to String.indexOf

```dart
Strings.indexOf('abcdef', 'abc);
-> 3
Strings.indexOf(null, 'abc);
-> -1
```

## lastIndexOf

Refer to String.lastIndexOf

```dart
Strings.lastIndexOf('abcdefabc', 'abc); 
-> 6 
Strings.lastIndexOf(null, 'abc); 
-> -1
```

## matchAsPrefix

```dart
Strings.matchAsPrefix(null, 'abc')
-> null
```

## padLeft

Refer to String.padLeft

```dart
Strings.padLeft('123', 4, '0');
-> 0123
Strings.padLeft(null, 4, '0');
-> 0000
```

## padRight

Refer to String.padRight

```dart
Strings.padRight('123', 4, '0');
-> 1230
Strings.padRight(null, 4, '0');
-> 0000
```

## replaceAll

Refer to String.replaceAll

```dart
Strings.replaceAll('abc', 'ab', 'A');
-> 'Ac'
Strings.replaceAll(null, 'ab', 'A');
-> ''
```

## replaceAllMapped

Refer to String.replaceAllMapped

```dart
Strings.replaceAllMapped('abc', 'a', (match) -> 'b');
-> 'bbc';
Strings.replaceAllMapped(null, 'a', (match) -> 'b');
-> ''
```

## replaceFirst

Refer to String.replaceFirst

```dart
Strings.replaceFirst('abcabc', 'abc', 'def);
-> 'defabc'
Strings.replaceFirst(null, 'abc', 'def);
-> ''
```

## replaceFirstMapped

Refer to String.replaceFirstMapped

```dart
Strings.replaceFirstMapped('abcabc', 'a', (match) -> 'b');
-> 'bbcabc';
Strings.replaceFirstMapped(null, 'a', (match) -> 'b');
-> ''
```

## replaceRange

Refer to String.replaceRange

```dart
Strings.replaceRange('abcdef', 3, 6, 'abc');
-> 'abcabc'
Strings.replaceRange(null, 3, 6, 'abc');
-> ''
```

## split

Refer to String.split

```dart
Strings.split('a,b,c,d', ',');
-> ['a', 'b', 'c', 'd'];
Strings.split(null, ',');
-> [];
```

## splitMapJoin

Refer to String.splitMapJoin

```dart
Strings.splitMapJoin('Eats sleeps leaves', RegExp(r'sleeps'),
     onMatch: (m) => '${m[0]}',
    onNonMatch: (n) => '*');
 -> '*sleeps*'
 Strings.splitMapJoin(null, RegExp(r'sleeps'),
     onMatch: (m) => '${m[0]}',
    onNonMatch: (n) => '*');
-> ''
```

## startsWith

Refer to String.startsWith

```dart
Strings.startsWith('abcdef', 'abc');
-> true
Strings.startsWith(null, 'abc');
-> false
```

## substring

Refer to String.substring

The Strings version of substring has special handling of a null string argument.

Instead of replacing it with an empty string we return a string containing spaces of the length required to fulfill the requested start/end index. If end is not passed then we return a single space.

```dart
Strings.substring('abcdef', 0, 3);
-> 'abc'
Strings.substring(null, 0, 3);
'   '
```

## toLowerCase

Refer to String.toLowerCase

```dart
Strings.toLowerCase('ABC');
-> 'abc'
Strings.toLowerCase(null);
-> '';
```

## toUpperCase

Refer to String.toUpperCase

```dart
Strings.toUpperCase('abc');
-> ABC
Strings.toUpperCase(null);
-> ''
```

## trim

Refer to String.trim

```dart
Strings.trim('  abc  ');
-> 'abc';
Strings.trim(null);
-> ''
```

## trimLeft

Refer to String.trimLeft

```dart
Strings.trimLeft('  abc ');
-> 'abc '
Strings.trimLeft(null);
-> ''
```

## trimRight

Refer to String.trimRight

```dart
Strings.trimRight('  abc ');
-> '  abc'
Strings.trimRight(null);
-> ''
```


# Style

The group of style related methods allows you to 'style' a string and test the style of a string.

## isLowerCase

```dart
 static bool isLowerCase(String? string) 
```

The 'isLowerCase' method returns true if the 'string' contains no upper case characters. All other characters, digits etc are allowed.

```dart
Strings.isLowerCase('abc 1234');
-> true
Strings.isLowerCase('abC 1234');
-> false
```

If null is passed the 'string' is treated as an empty string and 'true' is returned.

#### extension

The 'isLowerCase' method is available as an extension to the String class

```dart
'ABCD'.isLowerCase();
-> false
```

## isPrintable

```dart
static bool isPrintable(int? character) 
```

The isPrintable method returns true of 'character' is a printable character.

Whitespace characters are considered as non-printable.

```dart
Strings.isPrintable('\n');
-> false
```

## isUpperCase

```dart
 static bool isUpperCase(String? string) 
```

The 'isUpperCase' method returns true if the 'string' contains no lower case characters. All other characters, digits etc are allowed.

```dart
Strings.isUpperCase('ABC 1234');
-> true
Strings.isUpperCase('ABc 1234');
-> false
```

If null is passed the 'string' is treated as an empty string and 'true' is returned.

#### extension

The 'isUpperCase' method is available as an extension on the String class.

```dart
'abcd'.isUpperCase();
-> false
```

## startsWithLowerCase

```dart
 static bool startsWithLowerCase(String? string) 
```

The 'startsWithLowerCase' method returns true if the 'string' starts with an lower case character.

```dart
Strings.startsWithLowerCase('abc 1234');
-> true
Strings.startsWithLowerCase('Abc 1234');
-> false
```

If null is passed the 'string' is treated as an empty string and 'false' is returned.

#### extension

The method 'startsWithLowerCase' is available as an extension on the String class.

```dart
'abcDEF'.startsWithLowerCase();
-> true
```

## startsWithUpperCase

```dart
 static bool startsWithUpperCase(String? string) 
```

The 'startsWithUpperCase' method returns true if the 'string' starts with a lower case character.

```dart
Strings.startsWithUpperCase('ABC 1234');
-> true
Strings.startsWithUpperCase('abc 1234');
-> false
```

If null is passed the 'string' is treated as an empty string and 'false' is returned.

#### extension

The method 'startsWithUpperCase' is available as an extension method on the String class.

```dart
'ABC'.startsWithUpperCase();
-> true
```

## toCamelCase

```dart
 static String toCamelCase(String? string, {bool lower = fase});
```

The 'toCamelCase' method converts the `string` to camel case.&#x20;

```dart
Strings.toCamelCase('abc_one');
-> 'AbcOne'
```

If 'lower' is set to true then the first chacter of the resulting string is lowercase.

```dart
Strings.toCamelCase('abc_one', lower=true);
-> 'abcOne'
```

If null is passed the 'string' is treated as an empty string and an empty string is returned.

#### extension

The 'toCamelCase' method is available as an extension on the String class.

```dart
'abc_one'.toCamelCase();
-> 'AbcOne'
```

## toCapitalised

```dart
static String toCapitalised(String? string);
```

The 'toCapitalised' capitalises the first character of the 'string'.

```dart
Strings.toCapitalised('abc one');
-> 'Abc one'
```

If null is passed the 'string' is treated as an empty string and an empty string is returned.

#### extension

The 'toCapitialised' method is available as an extension on the String class.

```dart
'john'.toCapitalised();
-> 'John'
```

## toLowerCase

```dart
 static String toLowerCase(String? string);
```

The 'toLowerCase' method converts the `string` all lower case.

```dart
Strings.toLowerCase('Abc One');
-> 'abc one'
```

If null is passed the 'string' is treated as an empty string and an empty string is returned.

##

## toProperCase

```dart
 static String toProperCase(String? string);
```

The 'toProperCase' method converts the `string` to proper case where in the first letter of each word is capitalised.

```dart
Strings.toProperCase('abc one');
-> 'Abc One'
```

If null is passed the 'string' is treated as an empty string and an empty string is returned.

## toSnakeCase

```dart
 static String toSnakeCase(String? string);
```

The 'toSnakeCase' method converts the `string` to snake case where each word is separated by an underscore and all characters are lower case.

```dart
Strings.toSnakeCase('abc one');
-> 'abc_one'
Strings.toSnakeCase('AbcOne');
-> 'abc_one'
```

If null is passed the 'string' is treated as an empty string and an empty string is returned.

#### extension

The 'toSnakeCase' method is available as an extension method on the String class.

```dart
'AbcDef'.toSnakeCase();
-> 'abc_def'
```


# Transform

## reverse&#x20;

```dart
String reverse() 
```

The 'reverse' methods reverse the order of characters in a string:

```dart
Strings.reverse('1234');
-> '4321'
```

#### extension

The 'reverse' method is available as an extension to the String class.

```dart
'1234'.reverse();
-> '4321'
```

## toEscaped

```dart
static String toEscaped(String? string, {String Function(int charCode)? encode});
```

The 'toEscaped' escapes the following characters by proceeding them with a leading '\\'

* tab
* newline
* carriage return
* "
* '
* $

```dart
Strings.toEscaped('\t"$Hello"\r\n');
-> r'\t\"\$Hello\"\r\n"
```

If null is passed the 'string' is treated as an empty string and an empty string is returned.

The 'encode' function allows you to encode additional characters. As the string is escaped, 'encode' will be called for each character (except for the noted list above) allowing you to return an alternate encoding for that character.

```dart
Strings.toEscaped('abcd', encode: (character) -> character == 'a' ? 'AAA' : character);
-> AAAbcd
```

#### extension

The toEscaped method is available as an extension method on the String class.

```dart
'$abc'.toEscaped();
-> '\$abc'
```

## toPrintable

```dart
static String toPrintable(String? string);
```

The 'toPrintable' escapes the following characters by proceeding them with a leading '\\'

* tab
* newline
* carriage return

```dart
Strings.toPrintable('\t"$Hello"\r\n');
-> r'\t"$Hello"\r\n"
```

If null is passed the 'string' is treated as an empty string and an empty string is returned.

#### extension

The toPrintable method is available as an extension method on the String class.

```dart
'"$Hello".toPrintable();
-> r'\"$Hello"'
```

## toUnicode

```dart
static String toUnicode(int? charCode) 
```

The 'toUnicode' returns a unicode representation of the charCode.&#x20;

```dart
 print(toUnicode(50));
  -> \u0032
```

If null is passed an empty string is returned.


# Type

## isNumeric

```dart
 static bool isNumeric(String? string) 
```

The 'isNumeric' method checks if 'string' is numeric by attempting to parse it as a double.

Infinity and NaN are not treated as numbers.

```dart
Strings.isNumeric('abc');
-> false
Strings.isNumeric('1234');
-> true
```

If null is passed the 'string' is treated as an empty string and 'false' is returned.

#### extension

The 'isNumeric' method is available as an extension to the String class

```dart
'ABCD'.isNumeric();
-> false
```


