首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

.NET IndexOf 方法深度解析:C# 與 JavaScript 字串查找完整指南

     編輯:ASP.NET 基礎

方法簽名與核心行為

C# String.IndexOf

public int IndexOf(string value)
public int IndexOf(string value, int startIndex)
public int IndexOf(string value, int startIndex, int count)
public int IndexOf(char value)
public int IndexOf(char value, int startIndex)
public int IndexOf(char value, int startIndex, int count)
  • 回傳:0-based 索引,找不到回傳 -1
  • 搜尋方向:左至右
  • 區分大小寫:是 (序數比較)

JavaScript String.prototype.indexOf

str.indexOf(searchString[, fromIndex])
  • 回傳:0-based 索引,找不到回傳 -1
  • fromIndex 預設 0,負數視為 0,超過長度視為長度
  • 區分大小寫:是

常見陷阱與解決方案

陷阱 1:部分比對誤判

string a = "1,18,33";
bool has1 = a.IndexOf("1") > -1; // true,但其實是匹配到 "18" 的第一個字元

解決:使用正則表達式單詞邊界 `\b`

using System.Text.RegularExpressions;

bool hasExact1 = Regex.IsMatch(a, @"\b1\b"); // false,精確匹配獨立的 "1"

// 通用輔助方法
public static bool ContainsExact(string source, string target)
{
    if (string.IsNullOrEmpty(target)) return false;
    var escaped = Regex.Escape(target);
    return Regex.IsMatch(source, $@"\b{escaped}\b");
}

陷阱 2:startIndex 參數誤解

string s = "abcdef";
int pos = s.IndexOf("c", 3); // 從索引 3 (字元 'd') 開始找,找不到 → -1
// 正確:若想從 'c' 之後找,應用 s.IndexOf("c") + 1

陷阱 3:空字串行為

"abc".IndexOf("")     // 0
"".IndexOf("")        // 0
"abc".IndexOf("", 2)  // 2
// 空字串永遠在任意位置「找到」

進階用法與最佳實踐

1. 找出所有出現位置

public static List<int> FindAllIndexes(string source, string target)
{
    var list = new List<int>();
    int index = 0;
    while ((index = source.IndexOf(target, index)) != -1)
    {
        list.Add(index);
        index += target.Length; // 避免重疊匹配
    }
    return list;
}

2. 不區分大小寫搜尋

// C#:StringComparison.OrdinalIgnoreCase
int pos = s.IndexOf("hello", StringComparison.OrdinalIgnoreCase);

// JS:轉同大小寫後搜尋
var pos = s.toLowerCase().indexOf("hello");

3. 計算子字串出現次數

public static int CountOccurrences(string source, string target)
{
    if (string.IsNullOrEmpty(target)) return 0;
    int count = 0, index = 0;
    while ((index = source.IndexOf(target, index, StringComparison.Ordinal)) != -1)
    {
        count++;
        index += target.Length;
    }
    return count;
}

4. 搭配 Substring 切割

string url = "https://example.com/path?query=value";
int protoEnd = url.IndexOf("://");
int hostStart = protoEnd + 3;
int pathStart = url.IndexOf('/', hostStart);
string host = url.Substring(hostStart, pathStart - hostStart); // example.com

效能比較與替代方案

場景推薦做法理由
單次簡單查找IndexOf原生最快,無額外開銷
大量重複查找預先建立索引 / Trie / Aho-Corasick避免 O(n*m) 重複掃描
複雜模式匹配Regex功能強大,但較慢
不區分大小寫IndexOf(..., StringComparison.OrdinalIgnoreCase)比 ToLower() + IndexOf 省記憶體
byte[] / Span<byte> 搜尋MemoryExtensions.IndexOf (.NET Core 2.1+)零複製、高效能

總結

  • IndexOf 是字串查找基石,回傳 0-based 索引,找不到為 -1
  • 注意 部分比對陷阱,精確匹配請用 Regex.IsMatch(@"\b...\b")
  • startIndex 為搜尋起始位置,非「略過前 N 個匹配」
  • 跨語言開發時留意 C# / JS 參數順序與行為細微差異
  • 效能敏感場合可升級至 `Span` / `MemoryExtensions` 或專用演算法
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved