Files
PDFPatcher/App/Model/MatchPattern.cs
T
2022-01-06 09:08:16 +08:00

134 lines
3.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using PowerJson;
namespace PDFPatcher.Model
{
public sealed class MatchPattern : ICloneable
{
[XmlAttribute("名称")]
public string Name { get; set; }
[XmlAttribute("匹配模板")]
public string Text { get; set; }
[XmlAttribute("匹配大小写")]
public bool MatchCase { get; set; }
[XmlAttribute("匹配全标题")]
public bool FullMatch { get; set; }
[XmlAttribute("使用正则表达式")]
public bool UseRegularExpression { get; set; }
public MatchPattern() {
}
public MatchPattern(string text, bool matchCase, bool fullMatch, bool useRegExp) {
Text = text;
MatchCase = matchCase;
FullMatch = fullMatch;
UseRegularExpression = useRegExp;
}
public IMatcher CreateMatcher() {
if (UseRegularExpression) {
return new RegexMatcher(this);
}
return new SimpleMatcher(this);
}
#region ICloneable 成员
public object Clone() {
return new MatchPattern(Text, MatchCase, FullMatch, UseRegularExpression);
}
#endregion
public interface IMatcher
{
bool Matches(string text);
string Replace(string text, string replacement);
}
sealed class RegexMatcher : IMatcher
{
readonly Regex _regex;
readonly bool _fullMatch;
public RegexMatcher(MatchPattern pattern) {
_regex = new Regex(pattern.Text,
RegexOptions.Compiled | (pattern.MatchCase ? RegexOptions.None : RegexOptions.IgnoreCase));
_fullMatch = pattern.FullMatch;
}
public bool Matches(string text) {
var m = _regex.Match(text);
return m.Success && (_fullMatch == false || text.Length == m.Length);
}
public string Replace(string text, string replacement) {
return _regex.Replace(text, replacement);
}
}
sealed class SimpleMatcher : IMatcher
{
readonly bool _fullMatch;
readonly string _text;
readonly StringComparison _comparison;
public SimpleMatcher(MatchPattern pattern) {
_text = pattern.Text;
_fullMatch = pattern.FullMatch;
_comparison = pattern.MatchCase ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase;
}
public bool Matches(string text) {
if (String.IsNullOrEmpty(text)) {
return true;
}
if (_fullMatch && text.Length != _text.Length) {
return false;
}
var i = text.IndexOf(_text, _comparison);
return i != -1 && (_fullMatch == false || i == 0);
}
public string Replace(string text, string replacement) {
return Replace(text, _text, replacement, _comparison);
}
static string Replace(string original, string pattern, string replacement, StringComparison comparisonType) {
return Replace(original, pattern, replacement, comparisonType, -1);
}
static string Replace(string original, string pattern, string replacement, StringComparison comparisonType, int stringBuilderInitialSize) {
if (original == null) {
return null;
}
if (String.IsNullOrEmpty(pattern)) {
return original;
}
var posCurrent = 0;
var lenPattern = pattern.Length;
var idxNext = original.IndexOf(pattern, comparisonType);
var result = new StringBuilder(stringBuilderInitialSize < 0 ? Math.Min(4096, original.Length) : stringBuilderInitialSize);
while (idxNext >= 0) {
result.Append(original, posCurrent, idxNext - posCurrent);
result.Append(replacement);
posCurrent = idxNext + lenPattern;
idxNext = original.IndexOf(pattern, posCurrent, comparisonType);
}
result.Append(original, posCurrent, original.Length - posCurrent);
return result.ToString();
}
}
}
}