解决MySql布尔型新旧版本兼容问题,采用枚举来表示布尔型的数据表。由正向工程赋值
|
# ×Ö·û´®À©Õ¹ StringHelper
## ¸ÅÊö
`StringHelper` ÊÇ NewLife.Core ÖеÄ×Ö·û´®´¦Àí¹¤¾ßÀ࣬ÌṩÁ˷ḻµÄ×Ö·û´®À©Õ¹·½·¨£¬°üÀ¨±È½Ï¡¢½ØÈ¡¡¢²ð·Ö¡¢Æ´½Ó¡¢±à¼¾àÀëËÑË÷µÈ¹¦ÄÜ£¬¼«´ó¼ò»¯ÁËÈÕ³£¿ª·¢ÖеÄ×Ö·û´®²Ù×÷¡£
**ÃüÃû¿Õ¼ä**£º`NewLife`
**ÎĵµµØÖ·**£ºhttps://newlifex.com/core/string_helper
## ºËÐÄÌØÐÔ
- **¿ÕÖµ°²È«**£ºËùÓз½·¨¶¼ÄÜÕýÈ·´¦Àí null ºÍ¿Õ×Ö·û´®
- **ºöÂÔ´óСд**£ºÌṩ¶àÖÖºöÂÔ´óСдµÄ±È½Ï·½·¨
- **¸ßЧʵÏÖ**£ºÊ¹Óà `StringBuilder` ³Ø»¯¡¢`Span<T>` µÈ¼¼ÊõÓÅ»¯ÐÔÄÜ
- **Ä£ºýÆ¥Åä**£ºÄÚÖà Levenshtein ±à¼¾àÀëºÍ LCS ×¹«¹²×ÓÐòÁÐËã·¨
## ¿ìËÙ¿ªÊ¼
```csharp
using NewLife;
// ¿ÕÖµÅжÏ
var isEmpty = "".IsNullOrEmpty(); // true
var isBlank = " ".IsNullOrWhiteSpace(); // true
// ºöÂÔ´óСд±È½Ï
var equal = "Hello".EqualIgnoreCase("hello"); // true
// ×Ö·û´®²ð·Ö
var arr = "1,2,3".SplitAsInt(); // [1, 2, 3]
var dic = "a=1;b=2".SplitAsDictionary(); // {a:1, b:2}
// ×Ö·û´®Æ´½Ó
var str = new[] { 1, 2, 3 }.Join(","); // "1,2,3"
```
## API ²Î¿¼
### ¿ÕÖµÅжÏ
#### IsNullOrEmpty
```csharp
public static Boolean IsNullOrEmpty(this String? value)
```
ÅжÏ×Ö·û´®ÊÇ·ñΪ null »ò¿Õ×Ö·û´®¡£
**ʾÀý**£º
```csharp
String? s1 = null;
s1.IsNullOrEmpty() // true
"".IsNullOrEmpty() // true
" ".IsNullOrEmpty() // false£¨¿Õ¸ñ²»Ëã¿Õ£©
"hello".IsNullOrEmpty() // false
```
#### IsNullOrWhiteSpace
```csharp
public static Boolean IsNullOrWhiteSpace(this String? value)
```
ÅжÏ×Ö·û´®ÊÇ·ñΪ null¡¢¿Õ×Ö·û´®»ò½ö°üº¬¿Õ°××Ö·û¡£
**ʾÀý**£º
```csharp
String? s1 = null;
s1.IsNullOrWhiteSpace() // true
"".IsNullOrWhiteSpace() // true
" ".IsNullOrWhiteSpace() // true
"\t\n".IsNullOrWhiteSpace() // true
"hello".IsNullOrWhiteSpace() // false
```
### ×Ö·û´®±È½Ï
#### EqualIgnoreCase
```csharp
public static Boolean EqualIgnoreCase(this String? value, params String?[] strs)
```
ºöÂÔ´óСд±È½Ï×Ö·û´®ÊÇ·ñÓëÈÎÒâÒ»¸öºòÑ¡×Ö·û´®ÏàµÈ¡£
**ʾÀý**£º
```csharp
"Hello".EqualIgnoreCase("hello") // true
"Hello".EqualIgnoreCase("HELLO", "World") // true
"Hello".EqualIgnoreCase("World", "Test") // false
```
#### StartsWithIgnoreCase
```csharp
public static Boolean StartsWithIgnoreCase(this String? value, params String?[] strs)
```
ºöÂÔ´óСдÅжÏ×Ö·û´®ÊÇ·ñÒÔÈÎÒâÒ»¸öºòѡǰ׺¿ªÊ¼¡£
**ʾÀý**£º
```csharp
"HelloWorld".StartsWithIgnoreCase("hello") // true
"HelloWorld".StartsWithIgnoreCase("HELLO", "Hi") // true
```
#### EndsWithIgnoreCase
```csharp
public static Boolean EndsWithIgnoreCase(this String? value, params String?[] strs)
```
ºöÂÔ´óСдÅжÏ×Ö·û´®ÊÇ·ñÒÔÈÎÒâÒ»¸öºòÑ¡ºó׺½áÊø¡£
**ʾÀý**£º
```csharp
"HelloWorld".EndsWithIgnoreCase("world") // true
"HelloWorld".EndsWithIgnoreCase("WORLD", "Test") // true
```
### ͨÅä·ûÆ¥Åä
#### IsMatch
```csharp
public static Boolean IsMatch(this String pattern, String input, StringComparison comparisonType = StringComparison.CurrentCulture)
```
ʹÓÃͨÅä·ûģʽƥÅä×Ö·û´®£¬Ö§³Ö `*`£¨Æ¥ÅäÈÎÒⳤ¶È£©ºÍ `?`£¨Æ¥Åäµ¥¸ö×Ö·û£©¡£
**ÌØµã**£º
- ±ÈÕýÔò±í´ïʽ¸ü¼òµ¥¡¢¸ü¸ßЧ
- ʱ¼ä¸´ÔÓ¶È O(n) ~ O(n*m)
- ÎÞÐè¹¹ÔìÕýÔò¶ÔÏó
**ʾÀý**£º
```csharp
"*.txt".IsMatch("document.txt") // true
"*.txt".IsMatch("document.doc") // false
"file?.txt".IsMatch("file1.txt") // true
"file?.txt".IsMatch("file12.txt") // false
"*".IsMatch("anything") // true£¨Æ¥ÅäËùÓУ©
"test*end".IsMatch("test123end") // true
```
### ×Ö·û´®²ð·Ö
#### Split£¨À©Õ¹ÖØÔØ£©
```csharp
public static String[] Split(this String? value, params String[] separators)
```
°´Ö¸¶¨·Ö¸ô·û²ð·Ö×Ö·û´®£¬×Ô¶¯¹ýÂË¿ÕÌõÄ¿¡£
**ʾÀý**£º
```csharp
"a,b,,c".Split(",") // ["a", "b", "c"]£¨×Ô¶¯¹ýÂË¿ÕÏ
"a;b,c".Split(",", ";") // ["a", "b", "c"]
```
#### SplitAsInt
```csharp
public static Int32[] SplitAsInt(this String? value, params String[] separators)
```
²ð·Ö×Ö·û´®²¢×ª»»ÎªÕûÊýÊý×飬ĬÈÏʹÓöººÅºÍ·ÖºÅ×÷Ϊ·Ö¸ô·û¡£
**ÌØµã**£º
- ×Ô¶¯¹ýÂ˿ոñ
- ×Ô¶¯¹ýÂËÎÞЧÊý×Ö
- ±£ÁôÖØ¸´Ïî
**ʾÀý**£º
```csharp
"1,2,3".SplitAsInt() // [1, 2, 3]
"1, 2, 3".SplitAsInt() // [1, 2, 3]£¨×Ô¶¯È¥³ý¿Õ¸ñ£©
"1;2;3".SplitAsInt() // [1, 2, 3]£¨Ö§³Ö·ÖºÅ£©
"1,abc,3".SplitAsInt() // [1, 3]£¨¹ýÂËÎÞЧÏ
"1,1,2".SplitAsInt() // [1, 1, 2]£¨±£ÁôÖØ¸´£©
```
#### SplitAsDictionary
```csharp
public static IDictionary<String, String> SplitAsDictionary(
this String? value,
String nameValueSeparator = "=",
String separator = ";",
Boolean trimQuotation = false)
```
½«×Ö·û´®²ð·ÖΪ¼üÖµ¶Ô×ֵ䡣
**²ÎÊý˵Ã÷**£º
- `nameValueSeparator`£º¼üÖµ·Ö¸ô·û£¬Ä¬ÈÏ `=`
- `separator`£ºÌõÄ¿·Ö¸ô·û£¬Ä¬ÈÏ `;`
- `trimQuotation`£ºÊÇ·ñÈ¥³ýÖµÁ½¶ËµÄÒýºÅ
**ʾÀý**£º
```csharp
// »ù±¾Ó÷¨
"a=1;b=2".SplitAsDictionary()
// { "a": "1", "b": "2" }
// ×Ô¶¨Òå·Ö¸ô·û
"a:1,b:2".SplitAsDictionary(":", ",")
// { "a": "1", "b": "2" }
// È¥³ýÒýºÅ
"name='test';value=\"123\"".SplitAsDictionary("=", ";", true)
// { "name": "test", "value": "123" }
// ÎÞ¼üÃûʱʹÓÃÐòºÅ
"value1;key=value2".SplitAsDictionary()
// { "[0]": "value1", "key": "value2" }
```
> **Ìáʾ**£º·µ»ØµÄ×Öµä²»Çø·Ö´óСд£¨`StringComparer.OrdinalIgnoreCase`£©
### ×Ö·û´®Æ´½Ó
#### Join
```csharp
public static String Join(this IEnumerable value, String separator = ",")
public static String Join<T>(this IEnumerable<T> value, String separator = ",", Func<T, Object?>? func = null)
```
½«¼¯ºÏÔªËØÆ´½ÓΪ×Ö·û´®¡£
**ʾÀý**£º
```csharp
// »ù±¾Ó÷¨
new[] { 1, 2, 3 }.Join() // "1,2,3"
new[] { 1, 2, 3 }.Join(";") // "1;2;3"
// ʹÓÃת»»º¯Êý
var users = new[] { new { Name = "ÕÅÈý" }, new { Name = "ÀîËÄ" } };
users.Join(",", u => u.Name) // "ÕÅÈý,ÀîËÄ"
```
#### Separate
```csharp
public static StringBuilder Separate(this StringBuilder sb, String separator)
```
Ïò `StringBuilder` ×·¼Ó·Ö¸ô·û£¬µ«»áºöÂÔ¿ªÍ·£¨µÚÒ»´Îµ÷Óò»×·¼Ó£©¡£
**ʾÀý**£º
```csharp
var sb = new StringBuilder();
sb.Separate(",").Append("a"); // "a"
sb.Separate(",").Append("b"); // "a,b"
sb.Separate(",").Append("c"); // "a,b,c"
```
### ×Ö·û´®½ØÈ¡
#### Substring£¨À©Õ¹ÖØÔØ£©
```csharp
public static String Substring(this String str, String? after, String? before = null, Int32 startIndex = 0, Int32[]? positions = null)
```
´Ó×Ö·û´®ÖнØÈ¡Ö¸¶¨±ê¼ÇÖ®¼äµÄÄÚÈÝ¡£
**ʾÀý**£º
```csharp
// ½ØÈ¡±ê¼ÇÖ®ºóµÄÄÚÈÝ
"Hello[World]End".Substring("[") // "World]End"
// ½ØÈ¡Á½¸ö±ê¼ÇÖ®¼äµÄÄÚÈÝ
"Hello[World]End".Substring("[", "]") // "World"
// ½ØÈ¡±ê¼Ç֮ǰµÄÄÚÈÝ
"Hello[World]End".Substring(null, "[") // "Hello"
// »ñȡƥÅäλÖÃ
var positions = new Int32[2];
"Hello[World]End".Substring("[", "]", 0, positions);
// positions[0] = 6£¨ÄÚÈÝÆðʼλÖã©
// positions[1] = 11£¨ÄÚÈݽáÊøÎ»Öã©
```
#### Cut
```csharp
public static String Cut(this String str, Int32 maxLength, String? pad = null)
```
°´×î´ó³¤¶È½ØÈ¡×Ö·û´®£¬¿ÉÖ¸¶¨Ìî³ä×Ö·û¡£
**ʾÀý**£º
```csharp
"HelloWorld".Cut(8) // "HelloWor"
"HelloWorld".Cut(8, "...") // "Hello..."£¨×ܳ¤¶È²»³¬¹ý8£©
"Hi".Cut(8) // "Hi"£¨²»×㳤¶ÈÔÑù·µ»Ø£©
```
#### TrimStart / TrimEnd
```csharp
public static String TrimStart(this String str, params String[] starts)
public static String TrimEnd(this String str, params String[] ends)
```
´Ó×Ö·û´®¿ªÍ·/½áÎ²ÒÆ³ýÖ¸¶¨µÄ×Ó×Ö·û´®£¬²»Çø·Ö´óСд£¬Ö§³Ö¶à´ÎÆ¥Åä¡£
**ʾÀý**£º
```csharp
"HelloHelloWorld".TrimStart("Hello") // "World"£¨ÒƳýËùÓÐÆ¥ÅäµÄǰ׺£©
"WorldEndEnd".TrimEnd("End") // "World"
```
#### CutStart / CutEnd
```csharp
public static String CutStart(this String str, params String[] starts)
public static String CutEnd(this String str, params String[] ends)
```
ÒÆ³ýÖ¸¶¨×Ó×Ö·û´®¼°Æä֮ǰ/Ö®ºóµÄËùÓÐÄÚÈÝ¡£
**ʾÀý**£º
```csharp
"path/to/file.txt".CutStart("/") // "file.txt"
"path/to/file.txt".CutEnd("/") // "path/to"
```
#### EnsureStart / EnsureEnd
```csharp
public static String EnsureStart(this String? str, String start)
public static String EnsureEnd(this String? str, String end)
```
È·±£×Ö·û´®ÒÔÖ¸¶¨ÄÚÈÝ¿ªÊ¼/½áÊø¡£
**ʾÀý**£º
```csharp
"world".EnsureStart("Hello") // "Helloworld"
"Hello".EnsureStart("Hello") // "Hello"£¨ÒÑ´æÔÚÔò²»Ìí¼Ó£©
"/api/users".EnsureEnd("/") // "/api/users/"
"/api/users/".EnsureEnd("/") // "/api/users/"
```
#### TrimInvisible
```csharp
public static String? TrimInvisible(this String? value)
```
ÒÆ³ý×Ö·û´®ÖеIJ»¿É¼û ASCII ¿ØÖÆ×Ö·û£¨0-31 ºÍ 127£©¡£
**ʾÀý**£º
```csharp
"Hello\x00World\x1F".TrimInvisible() // "HelloWorld"
```
### ±àÂëת»»
#### GetBytes
```csharp
public static Byte[] GetBytes(this String? value, Encoding? encoding = null)
```
½«×Ö·û´®×ª»»Îª×Ö½ÚÊý×飬ĬÈÏʹÓà UTF-8 ±àÂë¡£
**ʾÀý**£º
```csharp
"Hello".GetBytes() // UTF-8 ±àÂëµÄ×Ö½ÚÊý×é
"Hello".GetBytes(Encoding.ASCII) // ASCII ±àÂë
"ÄãºÃ".GetBytes(Encoding.UTF8) // UTF-8 ±àÂëÖÐÎÄ
```
### Ä£ºýËÑË÷
#### Levenshtein ±à¼¾àÀë
```csharp
public static Int32 LevenshteinDistance(String str1, String str2)
public static String[] LevenshteinSearch(String key, String[] words)
```
¼ÆËãÁ½¸ö×Ö·û´®Ö®¼äµÄ±à¼¾àÀ루²åÈ롢ɾ³ý¡¢Ìæ»»²Ù×÷µÄ×îÉÙ´ÎÊý£©¡£
**ʾÀý**£º
```csharp
// ¼ÆËã±à¼¾àÀë
StringHelper.LevenshteinDistance("kitten", "sitting") // 3
// Ä£ºýËÑË÷
var words = new[] { "apple", "application", "banana", "apply" };
StringHelper.LevenshteinSearch("appl", words)
// ["apple", "application", "apply"]
```
#### LCS ×¹«¹²×ÓÐòÁÐ
```csharp
public static Int32 LCSDistance(String word, String[] keys)
public static String[] LCSSearch(String key, String[] words)
public static IEnumerable<T> LCSSearch<T>(this IEnumerable<T> list, String keys, Func<T, String> keySelector, Int32 count = -1)
```
»ùÓÚ×¹«¹²×ÓÐòÁеÄÄ£ºýËÑË÷£¬ÊʺÏÓÃÓÚËÑË÷½¨Òé¡¢×Ô¶¯²¹È«µÈ³¡¾°¡£
**ʾÀý**£º
```csharp
var words = new[] { "HelloWorld", "HelloKitty", "GoodBye" };
StringHelper.LCSSearch("Hello", words)
// ["HelloKitty", "HelloWorld"]
// ·ºÐÍËÑË÷
var users = new[] {
new { Id = 1, Name = "ÕÅÈý" },
new { Id = 2, Name = "ÕÅСÈý" },
new { Id = 3, Name = "ÀîËÄ" }
};
users.LCSSearch("ÕÅ", u => u.Name, 2)
// ·µ»ØÕÅÈý¡¢ÕÅСÈý
```
#### Match Ä£ºýÆ¥Åä
```csharp
public static IList<KeyValuePair<T, Double>> Match<T>(this IEnumerable<T> list, String keys, Func<T, String> keySelector)
public static IEnumerable<T> Match<T>(this IEnumerable<T> list, String keys, Func<T, String> keySelector, Int32 count, Double confidence = 0.5)
```
»ùÓÚÃüÖÐÂʺÍÌø¹ý³Í·£µÄÄ£ºýÆ¥ÅäËã·¨¡£
**ʾÀý**£º
```csharp
var products = new[] { "iPhone 15", "iPhone 15 Pro", "Samsung Galaxy" };
products.Match("iPhone", s => s, 2, 0.3)
// ["iPhone 15", "iPhone 15 Pro"]
```
### ÎÄ×ÖתÓïÒô
```csharp
public static void Speak(this String value)
public static void SpeakAsync(this String value)
```
µ÷ÓÃϵͳÓïÒôÒýÇæÀʶÁÎı¾£¨½ö Windows ƽ̨£©¡£
**ʾÀý**£º
```csharp
"ÄãºÃ£¬ÊÀ½ç".Speak(); // ͬ²½ÀʶÁ
"ÄãºÃ£¬ÊÀ½ç".SpeakAsync(); // Òì²½ÀʶÁ
```
## ×î¼Ñʵ¼ù
### 1. ʹÓÿÕÖµ°²È«µÄ·½·¨
```csharp
// ÍÆ¼ö£ºÊ¹ÓÃÀ©Õ¹·½·¨
if (str.IsNullOrEmpty()) return;
// ²»ÍƼö£ºÐèÒª´¦Àí null
if (str == null || str.Length == 0) return;
```
### 2. ½âÎöÅäÖÃ×Ö·û´®
```csharp
// Á¬½Ó×Ö·û´®½âÎö
var connStr = "Server=localhost;Database=test;User=root;Password=123456";
var dic = connStr.SplitAsDictionary();
var server = dic["Server"]; // "localhost"
var database = dic["Database"]; // "test"
```
### 3. URL ²ÎÊý½âÎö
```csharp
var query = "name=test&age=18&tags=a,b,c";
var dic = query.SplitAsDictionary("=", "&");
var name = dic["name"]; // "test"
var tags = dic["tags"].Split(","); // ["a", "b", "c"]
```
### 4. ʹÓà StringBuilder ³Ø
```csharp
using NewLife.Collections;
// ´Ó³ØÖлñÈ¡ StringBuilder
var sb = Pool.StringBuilder.Get();
sb.Append("Hello");
sb.Separate(",").Append("World");
// ·µ»Ø×Ö·û´®²¢¹é»¹µ½³Ø
var result = sb.Return(true); // "Hello,World"
```
## ÐÔÄÜ˵Ã÷
- `IsNullOrEmpty` ºÍ `IsNullOrWhiteSpace` ʹÓÃÄÚÁªÓÅ»¯
- ×Ö·û´®²ð·ÖºÍÆ´½ÓʹÓà `StringBuilder` ³Ø£¬¼õÉÙÄÚ´æ·ÖÅä
- ͨÅä·ûÆ¥ÅäʹÓõ¥Ö¸Õë»ØËÝËã·¨£¬±ÜÃâÕýÔò±í´ïʽ¿ªÏú
- ±à¼¾àÀëËã·¨Õë¶Ô¶Ì×Ö·û´®ÓÅ»¯
## Ïà¹ØÁ´½Ó
- [ÀàÐÍת»» Utility](/NewLife/X/Blob/dev/Doc/utility-ÀàÐÍת»»Utility.md)
- [Êý¾ÝÀ©Õ¹ IOHelper](/NewLife/X/Blob/dev/Doc/io_helper-Êý¾ÝÀ©Õ¹IOHelper.md)
- [·¾¶À©Õ¹ PathHelper](/NewLife/X/Blob/dev/Doc/path_helper-·¾¶À©Õ¹PathHelper.md)
|