Замените регулярное выражение на переменную скобки в C# - PullRequest
0 голосов
/ 11 февраля 2020

Я уверен, что это было задано ранее, но я не могу найти соответствующий вопрос (ы).

Будучи новичком в C# Regex , я хочу подражать c что возможно, например, с sed и awk, где я написал бы s/_(20[0-9]{2})[.0-9]{1}/\1/g, чтобы найти, получить число 4-ди git года после 2000, которое имеет подчеркивание в качестве префикса и число или точку после этого. \1 относится к значению в скобках.

Пример: Оба файла fx_201902.csv или fx_2019.csv должны вернуть мне myYear=2019. У меня не получилось:

string myYear = Regex.Replace(Path.GetFileName(x), @"_20([0-9]{2})[.0-9]{1}", "\1")

Как мне сбежать? Или такая замена невозможна? Если да, то как мне это сделать?

Редактировать: Моя проблема, как сделать /1 в C#, другими словами, как извлечь переменную регулярного выражения. Пожалуйста, простите мне мои опечатки в оригинальном сообщении - я пробую новое приложение SO и отправил его раньше, чем планировалось.

Ответы [ 4 ]

1 голос
/ 11 февраля 2020

Чтобы извлечь год с помощью Regex.Replace, вам нужно захватить только часть года строки в группу и заменить всю строку только группой захвата. Это означает, что вам также необходимо сопоставить символы до и после года, используя (например)

^.*_(20[0-9]{2})[.0-9].*$

, который затем можно заменить на $1 например

Regex r = new Regex(@"^.*_(20[0-9]{2})[.0-9].*$");
string filename = "fx_201902.csv";
string myYear = r.Replace(filename, "$1");
Console.WriteLine(myYear);
filename = "fx_2019.csv";
myYear = r.Replace(filename, "$1");
Console.WriteLine(myYear);

Вывод:

2019
2019

Если вы хотите исключить 2000 год из вашего матча, измените регулярное выражение на

^.*_(20(?:0[1-9]|[1-9][0-9]))[.0-9].*$
1 голос
/ 11 февраля 2020

Я бы предложил более надежное регулярное выражение: _(20(?:0[1-9]|[1-9][0-9]))[\d.]

Объяснение:

_ - соответствует _ буквально

(...) - первая группа захвата

20 - совпадение 20 буквально

(?:...) - группа без захвата

0[1-9]|[1-9][0-9] - чередование: совпадение 0 и di git, кроме 0 ИЛИ соответствует di git, отличному от нуля, за которым следуют любые цифры - это позволяет сопоставить ЛЮБОЙ год после 2000

[\d.] - соответствует точке или di git

И ниже как вы используете группы захвата:

var regex = new Regex(@"_(20(?:0[1-9]|[1-9][0-9]))[\d.]");
regex.Match("fx_201902.csv").Groups[1].Value;
// "2019"
regex.Match("fx_20190.csv").Groups[1].Value;
// "2019"
regex.Match("fx_2019.csv").Groups[1].Value;
// "2019"
1 голос
/ 11 февраля 2020

Вы можете использовать группу захвата для первых 4 цифр и сопоставить то, что находится до и после 4 цифр.

.*_(20[0-9]{2})[0-9]*\.\w+$

Пояснение

  • .*_ Соответствует последнему подчеркиванию
  • (20[0-9]{2}) Соответствует 20 и 2 цифрам
  • [0-9]*\. Соответствует 0 или более вхождения di git, за которым следует точка
  • \w+$ Совпадение с 1 или более символами слова до конца строки.

Regex demo | C# демо

При замене используйте:

$1

Например

string[] strings = {"fx_2019.csv", "fx_201902.csv"};
foreach (string s in strings)
{
    string myYear = Regex.Replace(s, @".*_(20[0-9]{2})[0-9]*\.\w+$", "$1");
    Console.WriteLine(myYear);
}

Выход

2019
2019
0 голосов
/ 11 февраля 2020

Ваш второй пример не содержит цифры месяца. Если вы все еще хотите захватить, сделайте его необязательным:

Regex.Replace(Path.GetFileName(x), @"_20([1-9]{2})([.0-9]{2})?", "\1")

Обратите внимание, что я добавил к вашему запросу только 3 символа: (, ) и ?

Если вы хотите, чтобы возвращаемое значение было таким, как ожидалось: измените замену на $ 1 из \ 1 как задокументировано (с правильной скобкой) и захват 2020, 2030, et c (все еще исключая 2000) с использованием или оператора и комбинацией [0-9] {1} и [ 1-9] {1} :

Regex.Replace(Path.GetFileName(x), @"_(20(([1-9]{1})([0-9]{1})||([0-9]{1})([1-9]{1})))([.0-9]{2})?", "$1")

Стоит отметить, что $ 3 и $ 4 соответствует последней и второй последней цифре; и $ 2 совпадает с последними 2 цифрами (или комбинацией [0-9] {1} [1-9] {1} || [1-9] {1} [0-9] {1 } ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...