1 回答

TA貢獻1827條經(jīng)驗 獲得超9個贊
可以通過檢查所有環(huán)境變量并檢查字符串中包含哪個變量的值,然后將字符串的該部分替換為%.
第一次天真的嘗試:
string Tokenify(string path)
{
foreach (DictionaryEntry e in Environment.GetEnvironmentVariables())
{
int index = path.IndexOf(e.Value.ToString());
if (index > -1)
{
//we need to make sure we're not already inside a tokenized part.
int numDelimiters = path.Take(index).Count(c => c == '%');
if (numDelimiters % 2 == 0)
{
path = path.Replace(e.Value.ToString(), $"%{e.Key.ToString()}%");
}
}
}
return path;
}
該代碼當前錯誤地假設環(huán)境變量的值在路徑中僅出現(xiàn)一次。這需要糾正,但我們暫時把它放在一邊。
另請注意,并非所有環(huán)境變量都代表目錄。例如,如果我在字符串 上運行此方法"6",我會得到"%PROCESSOR_LEVEL%"。Directory.Exists()這可以通過在使用環(huán)境變量值之前檢查它來解決。這也可能使得檢查我們是否已經(jīng)處于字符串的標記化部分中的需要變得無效。
您可能還想按長度對環(huán)境變量進行排序,以便始終使用最具體的變量。否則你可能會得到:
%HOMEDRIVE%%HOMEPATH%\AppData\Local\Folder
代替:
%LOCALAPPDATA%\Folder
更新了更喜歡最長變量的代碼:
string Tokenify(string path)
{
//first find all the environment variables that represent paths.
var validEnvVars = new List<KeyValuePair<string, string>>();
foreach (DictionaryEntry e in Environment.GetEnvironmentVariables())
{
string envPath = e.Value.ToString();
if (System.IO.Directory.Exists(envPath))
{
//this would be the place to add any other filters.
validEnvVars.Add(new KeyValuePair<string, string>(e.Key.ToString(), envPath));
}
}
//sort them by length so we always get the most specific one.
//if you are dealing with a large number of strings then orderedVars can be generated just once and cached.
var orderedVars = validEnvVars.OrderByDescending(kv => kv.Value.Length);
foreach (var kv in orderedVars)
{
//using regex just for case insensitivity. Otherwise just use string.Replace.
path = Regex.Replace(path, Regex.Escape(kv.Value), $"%{kv.Key}%", RegexOptions.IgnoreCase);
}
return path;
}
您可能仍然希望添加檢查以避免對字符串的部分進行雙重標記,但這在此版本中不太可能成為問題。
此外,您可能想過濾掉一些變量,例如驅動器根,例如 ( %HOMEDRIVE%) 或通過任何其他條件。
- 1 回答
- 0 關注
- 182 瀏覽
添加回答
舉報