Ну, ".*"
- жадный селектор. Вы делаете его неживым, используя ".*?"
. При использовании последней конструкции механизм регулярных выражений на каждом шаге соответствует тексту в "."
попытке сопоставления с тем, что происходит после ".*?"
. Это означает, что если, например, ничего не происходит после ".*?"
, то оно ничего не соответствует.
Вот что я использовал. s
содержит вашу исходную строку. Этот код специфичен для .NET, но большинство вариантов регулярного выражения будут иметь что-то подобное.
string m = Regex.Match(s, @"Project name: (?<name>.*?) J\d+").Groups["name"].Value;
Неочищенный путь:
. Проблема с вышеописанным методом заключается в том, что мы будем делать «нахождение» несколько раз, т. Е. Существует возможность каждый узел проходит несколько раз. Мы можем преодолеть эту проблему, если мы сможем записать информацию, чтобы не обрабатывать ее снова (подумайте о динамическом программировании).
Чтобы вместо этого найти каждый узел, мы сохраняем запись о том, что уже было найдено.
Лучший способ:
Код:
struct Node *
findCA(struct Node *root, struct Node *n1, struct Node *n2, int *set) {
int left_set, right_set;
left_set = right_set = 0;
struct Node *leftCA, *rightCA;
leftCA = rightCA = NULL;
if (root == NULL) {
return NULL;
}
if (root == n1 || root == n2) {
left_set = 1;
if (n1 == n2) {
right_set = 1;
}
}
if(!left_set) {
leftCA = findCA(root->left, n1, n2, &left_set);
if (leftCA) {
return leftCA;
}
}
if (!right_set) {
rightCA= findCA(root->right, n1, n2, &right_set);
if(rightCA) {
return rightCA;
}
}
if (left_set && right_set) {
return root;
} else {
*set = (left_set || right_set);
return NULL;
}
}