Files
2022-12-20 16:52:53 +08:00

253 lines
8.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ToolGood.Words.internals;
namespace ToolGood.Words.Benchmark.SearchExs
{
public sealed class StringSearchEx : BaseSearchEx
{
#region 查找 替换 查找第一个关键字 判断是否包含关键字
/// <summary>
/// 在文本中查找所有的关键字
/// </summary>
/// <param name="text">文本</param>
/// <returns></returns>
public List<string> FindAll(string text)
{
List<string> result = new List<string>();
var p = 0;
var txt = text.AsSpan();
for (int i = 0; i < txt.Length; i++) {
var t = _dict[txt[i]];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
for (int j = _end[next]; j < _end[next + 1]; j++) {
var index = _resultIndex[j];
var len = _keywordLengths[index];
var key = txt.Slice(i + 1 - len, len).ToString();
result.Add(key);
}
}
p = next;
}
return result;
}
public List<string> FindAll2(string text)
{
List<string> result = new List<string>();
var p = 0;
for (int i = 0; i < text.Length; i++) {
var t = _dict[text[i]];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
for (int j = _end[next]; j < _end[next + 1]; j++) {
var index = _resultIndex[j];
var len = _keywordLengths[index];
var key = text.AsSpan().Slice(i + 1 - len, len).ToString();
result.Add(key);
}
}
p = next;
}
return result;
}
public List<string> FindAll3(string text)
{
List<string> result = new List<string>();
var p = 0;
for (int i = 0; i < text.Length; i++) {
var t = _dict[text[i]];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
for (int j = _end[next]; j < _end[next + 1]; j++) {
var index = _resultIndex[j];
var len = _keywordLengths[index];
var key = text.Substring(i + 1 - len, len);
result.Add(key);
}
}
p = next;
}
return result;
}
/// <summary>
/// 在文本中查找第一个关键字
/// </summary>
/// <param name="text">文本</param>
/// <returns></returns>
public string FindFirst(string text)
{
var p = 0;
var txt = text.AsSpan();
for (int i = 0; i < txt.Length; i++) {
var t = _dict[txt[i]];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
var start = _end[next];
if (start < _end[next + 1]) {
var index = _resultIndex[start];
var len = _keywordLengths[index];
return txt.Slice(i + 1 - len, len).ToString();
}
}
p = next;
}
return null;
}
public string FindFirst2(string text)
{
var p = 0;
for (int i = 0; i < text.Length; i++) {
var t = _dict[text[i]];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
var start = _end[next];
if (start < _end[next + 1]) {
var index = _resultIndex[start];
var len = _keywordLengths[index];
return text.AsSpan(i + 1 - len, len).ToString();
}
}
p = next;
}
return null;
}
public string FindFirst3(string text)
{
var p = 0;
for (int i = 0; i < text.Length; i++) {
var t = _dict[text[i]];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
var start = _end[next];
if (start < _end[next + 1]) {
var index = _resultIndex[start];
var len = _keywordLengths[index];
return text.Substring(i + 1 - len, len);
}
}
p = next;
}
return null;
}
/// <summary>
/// 判断文本是否包含关键字
/// </summary>
/// <param name="text">文本</param>
/// <returns></returns>
public bool ContainsAny(string text)
{
var p = 0;
foreach (char t1 in text) {
var t = _dict[t1];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
if (_end[next] < _end[next + 1]) {
return true;
}
}
p = next;
}
return false;
}
/// <summary>
/// 在文本中替换所有的关键字
/// </summary>
/// <param name="text">文本</param>
/// <param name="replaceChar">替换符</param>
/// <returns></returns>
public string Replace(string text, char replaceChar = '*')
{
StringBuilder result = new StringBuilder(text);
var p = 0;
for (int i = 0; i < text.Length; i++) {
var t = _dict[text[i]];
if (t == 0) {
p = 0;
continue;
}
int next;
if (p == 0 || _nextIndex[p].TryGetValue(t, out next) == false) {
next = _first[t];
}
if (next != 0) {
var start = _end[next];
if (start < _end[next + 1]) {
var maxLength = _keywordLengths[_resultIndex[start]];
for (int j = i + 1 - maxLength; j <= i; j++) {
result[j] = replaceChar;
}
}
}
p = next;
}
return result.ToString();
}
#endregion
}
}