usr에서 언급했듯이 %(?<name>[^%]+)%
을 사용하여 검색 문자열의 모든 명명 된 자리 표시자를 추출 할 수 있습니다. 그러면 "그룹", "ep"및 "crc"가 나타납니다.
이제 모든 자리 표시자를 스캔하여 정규식의 각 자리 표시 자에 캡처해야합니다. 위에서 매치를 반복 할 것입니다 (각 자리 매김의 시작 오프셋과 길이를 통해 비 - 자리 표시 자 조각을 탐색 할 수 있습니다).
(귀하의 예제에서 실수가있다, 내가 마지막 부분은 정확하고 내가 (신비를 삭제하고있어 가정합니다 ...))
그것은 다음과 같습니다 정규식 구축 할 것입니다 :
를
^%(?<group>.*?)_Suite_Precure_(?<ep>.*?)_(?<crc>.*?).mkv$
문제가있는 문자를 올바르게 처리하기 위해 리터럴 조각을 정규식에서 사용하기 전에 Regex.Escape에 전달하십시오.
이제 각 파일 이름에 대해 정규식과 일치 시키려고합니다. 일치하는 경우이 파일의 자리 표시 자 값을 가져옵니다. 그런 다음 해당 자리 표시 자 값을 가져 와서 출력 패턴으로 병합하여 자리 표시자를 바꿉니다. 이것은 당신에게 새로운 이름을주고, 당신은 이름을 바꿀 수 있습니다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace renamer
{
class RenameImpl
{
public static IEnumerable<Tuple<string,string>> RenameWithPatterns(
string path, string curpattern, string newpattern,
bool caseSensitive)
{
var placeholderNames = new List<string>();
// Extract all the cur_placeholders from the user's input pattern
var input_regex = new Regex(@"(\%[^%]+\%)");
var cur_matches = input_regex.Matches(curpattern);
var new_matches = input_regex.Matches(newpattern);
var regex_pattern = new StringBuilder();
if (!caseSensitive)
regex_pattern.Append("(?i)");
regex_pattern.Append('^');
// Do a pass over the matches and grab info about each capture
var cur_placeholders = new List<Tuple<string, int, int>>();
var new_placeholders = new List<Tuple<string, int, int>>();
for (var i = 0; i < cur_matches.Count; ++i)
{
var m = cur_matches[i];
cur_placeholders.Add(new Tuple<string, int, int>(
m.Value, m.Index, m.Length));
}
for (var i = 0; i < new_matches.Count; ++i)
{
var m = new_matches[i];
new_placeholders.Add(new Tuple<string, int, int>(
m.Value, m.Index, m.Length));
}
// Build the regular expression
for (var i = 0; i < cur_placeholders.Count; ++i)
{
var ph = cur_placeholders[i];
// Get the literal before the first capture if it is the first
if (i == 0 && ph.Item2 > 0)
regex_pattern.Append(Regex.Escape(
curpattern.Substring(0, ph.Item2)));
// Generate the capture for the placeholder
regex_pattern.AppendFormat("(?<{0}>.*?)",
ph.Item1.Replace("%", ""));
// The literal after the placeholder
if (i + 1 == cur_placeholders.Count)
regex_pattern.Append(Regex.Escape(
curpattern.Substring(ph.Item2 + ph.Item3)));
else
regex_pattern.Append(Regex.Escape(
curpattern.Substring(ph.Item2 + ph.Item3,
cur_placeholders[i + 1].Item2 - (ph.Item2 + ph.Item3))));
}
regex_pattern.Append('$');
var re = new Regex(regex_pattern.ToString());
foreach (var pathname in Directory.EnumerateFileSystemEntries(path))
{
var file = Path.GetFileName(pathname);
var m = re.Match(file);
if (!m.Success)
continue;
// New name is initially same as target pattern
var newname = newpattern;
// Iterate through the placeholder names
for (var i = new_placeholders.Count; i > 0; --i)
{
// Target placeholder name
var tn = new_placeholders[i-1].Item1.Replace("%", "");
// Get captured value for this capture
var ct = m.Groups[tn].Value;
// Perform the replacement
newname = newname.Remove(new_placeholders[i - 1].Item2,
new_placeholders[i - 1].Item3);
newname = newname.Insert(new_placeholders[i - 1].Item2, ct);
}
newname = Path.Combine(path, newname);
yield return new Tuple<string, string>(pathname, newname);
}
}
}
}
항상 입력 및 출력 예제를 추가하십시오. 1000 % 더 선명 해집니다. –
나는 대답 한 후에 당신이 당신의 질문을 명확히했음을 안다. 도움이되지 않았나요? – usr
@usr 귀하의 답변은 언뜻보기에 CRC를 캡처 할 때 CRC의 정확한 값을 알아야만하는 것처럼 보였습니다. 나는 그것을 읽는 것을 잘못했을 수도있다. – agent154