В Python re.search()
возвращает ТОЛЬКО первое совпадение предложения, и ничего после этого.
Вы должны попробовать re.findall(x)
в своем коде.
Всегда помните, что 0-й индекс совпадения (group(0)
) возвращает полную строку, которая соответствует, поэтому похоже, что есть два x
, но первый фактически является просто строкой, сопоставленной целое регулярное выражение .
Когда вы использовали group(1)
, был возвращен только текст в первых скобках ()
, который оказался таким же, как и в group(0)
.
TL; DR
Используйте re.search()
для определения только первого совпадения и используйте re.findall()
для извлечения нескольких совпадений.
Поскольку другие отправили, Вы не можете выйти из цикла в ForEach.
Могут Вы для использования LINQ? Если так, Вы могли легко объединить TakeWhile и пользовательский метод расширения ForEach (который примерно каждый проект, кажется, имеет в эти дни).
В Вашем примере, однако, List<T>.FindIndex
была бы лучшая альтернатива - но если Вы на самом деле не делаете этого, отправьте пример того, что Вы действительно хотите сделать.
Нет никакого цикла, к которому у каждого есть доступ, от которого можно повредиться. И каждый вызов (анонимному) делегату является новым вызовом функции, таким образом, локальные переменные не помогут. Но так как C# дает Вам закрытие, можно установить флаг и затем ничего не сделать в дальнейших вызовах:
bool stop = false;
myList.ForEach((a) => {
if (stop) {
return;
} else if (a.SomeCondition()) {
stop = true;
}
});
(Это должно быть протестировано, чтобы проверить, сгенерирована ли корректная ссылочная семантика для закрытия.)
А более усовершенствованный подход должен был бы создать Ваш собственный дополнительный метод, который позволил делегату возвращать false для остановки цикла:
static class MyExtensions {
static void ForEachStoppable<T>(this IEnumerable<T> input, Func<T, bool> action) {
foreach (T t in input) {
if (!action(t)) {
break;
}
}
}
}
Вы имеете LINQ доступный Вам? Ваша логика кажется подобной Любому:
bool any = blackList.Any(s=>inputString.Contains(s));
, который совпадает с:
bool any = blackList.Any(inputString.Contains);
, Если у Вас нет LINQ, затем это - все еще то же как:
bool any = blackList.Find(inputString.Contains) != null;
, Если Вы хотите выполнить дополнительную логику, существуют вещи, которые можно сделать (с LINQ) с TakeWhile
и т.д.
Я не думаю, что существует изящный способ сделать это при использовании метода ForEach. hacky решение состоит в том, чтобы выдать исключение.
, Что препятствует тому, чтобы Вы делали старомодный foreach?
foreach (string item in blackList)
{
if (!inputString.Contains(item)) continue;
result = true;
break;
}
Если Вы хотите цикл, используйте цикл.
Action
не допускает возвращаемого значения, таким образом, нет никакого способа, которым функция ForEach могла возможно знать, что Вы хотите повредиться, за исключением выдачи исключения. Используя исключение вот излишество.
Единственный способ "выйти" из цикла состоит в том, чтобы выдать исключение. Нет никакого стиля "повреждения", способ выйти из.ForEach метода как Вы был бы нормальный цикл foreach.
Метод ForEach не является средним, чтобы сделать это. Если Вы хотите знать, содержит ли набор объект, необходимо использовать, Содержит метод. И если Вы хотите выполнить проверку на всех объектах в наборе, необходимо попробовать Любой метод расширения.
class Program
{
static void Main(string[] args)
{
List<string> blackList = new List<string>(new[] { "jaime", "jhon", "febres", "velez" });
string inputString = "febres";
bool result = false;
blackList.ForEach((item) =>
{
Console.WriteLine("Executing");
if (inputString.Contains(item))
{
result = true;
Console.WriteLine("Founded!");
}
},
() => result);
Console.WriteLine(result);
Console.ReadLine();
}
}
public static class MyExtensions
{
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action, Func<bool> breakOn)
{
foreach (var item in enumerable)
{
action(item);
if (breakOn())
{
break;
}
}
}
}
bool @break = false;
blackList.ForEach(item =>
{
if(!@break && inputString.Contains(item))
{ @break = true;
result = true;
}
if (@break) return;
/* ... */
});
Примечание, которого вышеупомянутое все еще выполнит итерации через каждый объект, но возврат сразу. Конечно, этот путь, вероятно, не так хорош как нормальное foreach
.