String заменить с помощью List <string>
У меня есть список слов, которые я хочу игнорировать, как этот:
public List<String> ignoreList = new List<String>()
{
"North",
"South",
"East",
"West"
};
Для данной строки, скажем "14th Avenue North"
, я хочу удалить часть "Север", поэтому в основном функция, которая будет возвращать "14th Avenue "
при вызове.
Я чувствую, что есть что-то, что я должен сделать с сочетанием LINQ, regex и replace, но я просто не могу понять это.
Чем больше картина, тем я пытаюсь написать алгоритм сопоставления адресов. Я хочу отфильтровать слова типа "Улица", "Север", "Бульвар" и т.д., Прежде чем использовать алгоритм Левенштейна для оценки сходства.
Ответы
Ответ 1
Как насчет этого:
string.Join(" ", text.Split().Where(w => !ignoreList.Contains(w)));
или для .Net 3:
string.Join(" ", text.Split().Where(w => !ignoreList.Contains(w)).ToArray());
Обратите внимание, что этот метод разбивает строку на отдельные слова, чтобы удалить только целые слова. Таким образом, он будет корректно работать с такими адресами, как Northampton Way #123
, с которыми не может обрабатываться string.Replace
.
Ответ 2
Regex r = new Regex(string.Join("|", ignoreList.Select(s => Regex.Escape(s)).ToArray()));
string s = "14th Avenue North";
s = r.Replace(s, string.Empty);
Ответ 3
Что-то вроде этого должно работать:
string FilterAllValuesFromIgnoreList(string someStringToFilter)
{
return ignoreList.Aggregate(someStringToFilter, (str, filter)=>str.Replace(filter, ""));
}
Ответ 4
Что не так с простой петлей?
string street = "14th Avenue North";
foreach (string word in ignoreList)
{
street = street.Replace(word, string.Empty);
}
Ответ 5
Если вы знаете, что список слов содержит только символы, которые не требуют экранирования внутри регулярного выражения, вы можете сделать это:
string s = "14th Avenue North";
Regex regex = new Regex(string.Format(@"\b({0})\b",
string.Join("|", ignoreList.ToArray())));
s = regex.Replace(s, "");
Результат:
14th Avenue
Если есть специальные символы, вам нужно исправить две вещи:
- Используйте Regex.Escape для каждого элемента списка игнорирования.
- Слово-граница
\b
не будет соответствовать пробелу, за которым следует символ, или наоборот. Вам может потребоваться проверить пробелы (или другие разделительные символы, такие как пунктуация), используя вместо них утверждения поиска.
Здесь, как исправить эти две проблемы:
Regex regex = new Regex(string.Format(@"(?<= |^)({0})(?= |$)",
string.Join("|", ignoreList.Select(x => Regex.Escape(x)).ToArray())));
Ответ 6
Если это короткая строка, как в вашем примере, вы можете просто зациклировать строки и заменить их по одному. Если вы хотите получить фантазию, вы можете использовать метод LINQ Aggregate для этого:
address = ignoreList.Aggregate(address, (a, s) => a.Replace(s, String.Empty));
Если это большая строка, это будет медленным. Вместо этого вы можете заменить все строки за один проход через строку, что намного быстрее. Я сделал способ для этого в этом ответе.
Ответ 7
LINQ упрощает и читает. Это требует нормализованных данных, хотя, в частности, в том, что он чувствителен к регистру.
List<string> ignoreList = new List<string>()
{
"North",
"South",
"East",
"West"
};
string s = "123 West 5th St"
.Split(' ') // Separate the words to an array
.ToList() // Convert array to TList<>
.Except(ignoreList) // Remove ignored keywords
.Aggregate((s1, s2) => s1 + " " + s2); // Reconstruct the string
Ответ 8
public static string Trim(string text)
{
var rv = text;
foreach (var ignore in ignoreList)
rv = rv.Replace(ignore, "");
return rv;
}
Обновлено для Gabe
public static string Trim(string text)
{
var rv = "";
var words = text.Split(" ");
foreach (var word in words)
{
var present = false;
foreach (var ignore in ignoreList)
if (word == ignore)
present = true;
if (!present)
rv += word;
}
return rv;
}
Ответ 9
Если у вас есть список, я думаю, вам придется прикоснуться ко всем предметам. Вы можете создать массив RegEx со всеми вашими игнорирующими ключевыми словами и заменить на String.Empty
.
Здесь начинается:
(^|\s+)(North|South|East|West){1,2}(ern)?(\s+|$)
Если у вас есть один RegEx для игнорирования слов, вы можете сделать одну замену для каждой фразы, которую вы хотите передать алгоритму.
Ответ 10
Почему бы не шутки держать его просто?
public static string Trim(string text)
{
var rv = text.trim();
foreach (var ignore in ignoreList) {
if(tv.EndsWith(ignore) {
rv = rv.Replace(ignore, string.Empty);
}
}
return rv;
}
Ответ 11
Вы можете сделать это с помощью выражения и выражения, если хотите, но проще повернуть его, чем с помощью агрегата. Я бы сделал что-то вроде этого:
string s = "14th Avenue North"
ignoreList.ForEach(i => s = s.Replace(i, ""));
//result is "14th Avenue "