/// <summary> /// Evaluates the selected <see cref="Pattern"/>. /// </summary> /// <remarks> /// As most of the other evaluation methods, it repositions the /// <see cref="EvaluationContextBase.Source"/> navigator on the root node. /// <para> /// Clears the <see cref="EvaluationContextBase.Matched"/> object before /// proceeding, as the restriction about node mathing (see <linkref id="schematron" />) /// applies only inside a single pattern. /// </para> /// </remarks> /// <param name="pattern">The <see cref="Pattern"/> to evaluate.</param> /// <param name="output">Contains the builder to accumulate messages in.</param> /// <returns>A boolean indicating if a new message was added.</returns> private bool Evaluate(Pattern pattern, StringBuilder output) { bool failed = false; Source.MoveToRoot(); StringBuilder sb = new StringBuilder(); // Reset matched nodes, as across patters, nodes can be // evaluated more than once. Matched.Clear(); foreach (Rule rule in pattern.Rules) { if (Evaluate(rule, sb)) { failed = true; } } if (failed) { Formatter.Format(pattern, Source, sb); output.Append(sb.ToString()); } return(failed); }
public MatchedAssertion(Matched <T> matched) { this.matched = matched; constraints = new List <Constraint>(); not = false; name = "Match"; }
public Matched <T> Match <T>(T value) { var matcher = new Matched <T>(this, value); Matchers.Add(matcher); return(matcher); }
public static IEnumerable <T> TakeMatch <T>( this IEnumerable <T> sequence, Matched <T> onMatch, UnMatched <T> onNoMatch, IEnumerable <Predicate <T> > predicates) { IEnumerable <T> pending = sequence; List <T> scanned = new List <T>(); while (pending.Any() && predicates.Any()) { var window = pending. TakeWhile((elem, index) => index < predicates.Count() && predicates.ElementAt(index)(elem)); if (window.Count() == predicates.Count()) { onMatch(scanned, window); return(pending.Skip(predicates.Count())); } else { scanned.Add(pending.First()); pending = pending.Skip(1); } } onNoMatch(scanned); return(pending); }
public Matched <T> Match <T>() { var matcher = new Matched <T>(this); Matchers.Add(matcher); return(matcher); }
protected virtual void Subscriber_Matched(object sender, TEventResult e) { if (e == null) return; Matched?.Invoke(sender, e); }
/// <summary> /// This implementation clears all previous display and uses the /// result display engine to render a new set of hit result onto the /// rich text box. /// </summary> /// <param name="Match"></param> public void Build_ResultRichTextArea(Matched Match) { richTxtDisplay.Blocks.Clear(); if (Sequences == null) throw new Exception ("No sequence to attach to result!" + "Please check the sequences variable before proceeding."); richTxtDisplay.Blocks.Add (ResultDisplayLogic.GetRichHeader (Match.SequenceName, Match.MatchAt_StartPosition, Match.Match_EndPosition)); foreach(SequenceContract sequence in Sequences) if (sequence.Name.Equals(Match.SequenceName)) { richTxtDisplay.Blocks.Add(ResultDisplayLogic.GetHitDetails (sequence.Characters, Match.MatchAt_StartPosition, Match.Match_EndPosition)); return; } throw new Exception ("Unable to find the appropriate sequence to display out hit result!"); }
public Matched <T> Match <T>(Predicate <T> what) { var matcher = new Matched <T>(this, what); Matchers.Add(matcher); return(matcher); }
public void BreakMatch(ManualMatchedPair <TInternal, TExternal> pair) { Matched.Remove(pair); pair.Internal.Status = MatchStatus.Dirty; pair.External.Status = MatchStatus.Dirty; UnmatchedInternals.Add(pair.Internal); UnmatchedExternals.Add(pair.External); }
public void AddMatch(TInternal _internal, MatchStatus internalStatus, TExternal _external, MatchStatus externalStatus) { Matched.Add(new ManualMatchedPair <TInternal, TExternal>( this, new ManualMatchItem <TInternal>(_internal, internalStatus, InternalHandler), new ManualMatchItem <TExternal>(_external, externalStatus, ExternalHandler) )); }
protected override void WriteImageFile() { PerfImage.Width = 900; PerfImage.Height = 400; string meanImage = ImageFileName + ".mean.png"; IEnumerable <double> means = Matched.Select(a => 100 * (a.Value.Mean - a.Key.Mean) / a.Key.Mean); WriteImageFile(meanImage, "Mean", means); }
/// <summary> /// Evaluates the selected <see cref="Rule"/>. /// </summary> /// <remarks> /// <see cref="Rule.Asserts"/> and <see cref="Rule.Reports"/> are iterated /// and each <see cref="Assert"/> and <see cref="Report"/> is executed against /// the context selected by the <see cref="Rule.Context"/>. /// <para> /// Nodes matched are added to the <see cref="EvaluationContextBase.Matched"/> list of /// nodes to skip in the next rule, using the <see cref="IMatchedNodes.AddMatched"/> method. /// This object is a strategy object which implements different algorithms for matching and /// saving node references, as the actual <see cref="XPathNavigator"/> implementation provides /// different methods for accessing the underlying source. /// <para> /// This makes the implementation both performant and compliant with /// the restriction about node mathing (see <linkref id="schematron" />) in the spec. /// </para> /// <para> /// <seealso cref="DomMatchedNodes"/> /// <seealso cref="XPathMatchedNodes"/> /// <seealso cref="GenericMatchedNodes"/> /// </para> /// As most of the other evaluation methods, it repositions the /// <see cref="EvaluationContextBase.Source"/> navigator on the root node. /// </para> /// </remarks> /// <param name="rule">The <see cref="Rule"/> to evaluate.</param> /// <param name="output">Contains the builder to accumulate messages in.</param> /// <returns>A boolean indicating if a new message was added.</returns> /// <exception cref="InvalidOperationException"> /// The rule to evaluate is abstract (see <see cref="Rule.IsAbstract"/>). /// </exception> private bool Evaluate(Rule rule, StringBuilder output) { if (rule.IsAbstract) { throw new InvalidOperationException("The Rule is abstract, so it can't be evaluated."); } bool failed = false; StringBuilder sb = new StringBuilder(); Source.MoveToRoot(); XPathNodeIterator nodes = Source.Select(rule.CompiledExpression); ArrayList evaluables = new ArrayList(nodes.Count); // The navigator doesn't contain line info while (nodes.MoveNext()) { if (!Matched.IsMatched(nodes.Current)) { // Add the navigator to the list to be evaluated and to // the list of pattern-level nodes matched so far. XPathNavigator curr = nodes.Current.Clone(); evaluables.Add(curr); Matched.AddMatched(curr); } } foreach (Assert asr in rule.Asserts) { foreach (XPathNavigator node in evaluables) { if (EvaluateAssert(asr, node.Clone(), sb)) { failed = true; } } } foreach (Report rpt in rule.Reports) { foreach (XPathNavigator node in evaluables) { if (EvaluateReport(rpt, node.Clone(), sb)) { failed = true; } } } if (failed) { Formatter.Format(rule, Source, sb); output.Append(sb.ToString()); } return(failed); }
void Sort <T>(Func <ManualMatchedPair <TInternal, TExternal>, T> sortKey) { var list = Matched.OrderBy(sortKey).ToList(); Matched.Clear(); foreach (var e in list) { Matched.Add(e); } }
/// <summary> /// Perform certain task till specified condition is matched /// </summary> /// <param name="do">Delegate executed repeatedly at recheck interval of Clock. The return value is used as argument for "matched" delegate.</param> /// <param name="matched">The return value of the "do" delegate passed as argument to this delegate. Return value of true would cause the /// Clock to stop.</param> /// <param name="expired">In case of a no match this delegate is called</param> /// <returns></returns> public virtual object Perform(Do @do, Matched matched, Expired expired) { while (true) { object o = @do(); if (matched(o)) return o; if (TimeUp) return expired(); Thread.Sleep(recheckAfterInMilliSeconds); } }
/// <summary> /// 指定した入力文字列内で、正規表現パターンと一致する箇所を検索しすべて列挙します。 /// </summary> /// <param name="input">検索対象とする入力文字列</param> /// <param name="startat">検索開始文字位置(省略時は先頭から検索)</param> /// <returns>検索によって見つかった Matched オブジェクトの列挙</returns> public IEnumerable <Matched> Matches(string input, int startat = 0) { Matched match = Match(input, startat); while (match != null) { yield return(match); match = match.NextMatch(); } }
void MakeMatch() { if (SelectedExternal == null || SelectedExternal == null) { return; } SelectedInternal.Status = MatchStatus.NewMatch; SelectedExternal.Status = MatchStatus.NewMatch; Matched.Insert(0, new ManualMatchedPair <TInternal, TExternal>(this, SelectedInternal, SelectedExternal)); UnmatchedInternals.Remove(SelectedInternal); UnmatchedExternals.Remove(SelectedExternal); }
/// <summary> /// Evaluates the selected <see cref="Pattern"/>. /// </summary> /// <remarks> /// Processing is synchronous, as rules must me evaluated in document order. /// <para> /// As most of the other evaluation methods, it repositions the /// <see cref="EvaluationContextBase.Source"/> navigator on the root node. /// </para> /// <para> /// Clears the <see cref="EvaluationContextBase.Matched"/> object before /// proceeding, as the restriction about node mathing (see <link ref="schematron" />) /// applies only inside a single pattern. /// </para> /// </remarks> /// <param name="pattern">The <see cref="Pattern"/> to evaluate.</param> /// <returns>The messages accumulated by the evaluation of all the child /// <see cref="Rule"/>, or <see cref="String.Empty"/> if there are no messages.</returns> private string Evaluate(Pattern pattern) { Source.MoveToRoot(); StringBuilder sb = new StringBuilder(); // Reset matched nodes, as across patters, nodes can be // evaluated more than once. Matched.Clear(); foreach (Rule rule in pattern.Rules) { sb.Append(Evaluate(rule)); } string res = sb.ToString(); return(Formatter.Format(pattern, res, Source)); }
/// <summary> /// shows finalized matches in a data grid /// </summary> /// <param name="MatchList"></param> /// <param name="dataGridView1"></param> void DisplayMatches(/*List<Match> MatchList, DataGridView dataGridView1*/) { dataGridView1.Columns.Clear(); dataGridView1.ColumnCount = 3; dataGridView1.Columns[0].HeaderText = "Big:"; dataGridView1.Columns[1].HeaderText = "Little:"; dataGridView1.Columns[2].HeaderText = "Match Rank:"; int AvgRank = 0; foreach (Match m in Matched) { AvgRank += m.matchRating; string[] row = { m.Brother.FullName, m.Pledge.FullName, "" + m.matchRating }; dataGridView1.Rows.Add(row); } //AvgRank /= MatchList.Count; string[] AverageRank = { "", "Average Ranking: ", "" + ((double)AvgRank) / ((double)Matched.Count) }; dataGridView1.Rows.Insert(0, AverageRank); //write list of unmatched brothers to datagrid2 dataGridView2.Columns.Clear(); dataGridView2.ColumnCount = 6; dataGridView2.Columns[0].HeaderText = "Remaining Brothers:"; dataGridView2.Columns[1].HeaderText = "Choice 1: "; dataGridView2.Columns[2].HeaderText = "Choice 2: "; dataGridView2.Columns[3].HeaderText = "Choice 3: "; dataGridView2.Columns[4].HeaderText = "Choice 4: "; dataGridView2.Columns[5].HeaderText = "Choice 5: "; foreach (BrotherObject b in Brothers) { if (Matched.Exists(m => m.Brother.FullName == b.FullName) == false) { string[] row = new string[6]; row[0] = b.FullName; for (int i = 0; i < 5; i++) { row[i + 1] = (b.LittleChoices[i] != null) ? b.LittleChoices[i] : ""; } dataGridView2.Rows.Add(row); } } }
/// <summary> /// If a <see cref="ICategory"/> exists in the <paramref name="categories"/> then it either adds the <paramref name="value"/> /// to the <see cref="ICategory.matched"/> list of it updates the <see cref="IMatched.weight"/> and <seealso cref="ICategory.total_weight"/> accordingly. /// If a <see cref="ICategory"/> doesn't exist, then it simply adds it to the list. The majority of the work is done if a <see cref="ICategory"/> /// already exists and it needs to be updated accordingly /// </summary> public static void AddCategory(this ICollection <ICategory> categories, string model_name, string value) { var category = categories .FirstOrDefault(x => x.name == model_name); if (category != null && category.matched .Any(x => string.Compare(x.value, value, true) == 0)) { category.matched .FirstOrDefault(x => string.Compare(x.value, value, true) == 0) .weight++; } else if (category != null && category.matched .Any(x => string.Compare(x.value, value, true) != 0)) { var new_matched = new Matched() { value = value }; new_matched.weight++; category.matched.Add(new_matched); } else { var new_category = new Category() { name = model_name }; var new_matched = new Matched() { value = value }; new_matched.weight++; new_category.matched.Add(new_matched); categories.Add(new_category); } }
//TODO: Distribution public override Expression GetExpression(IReadOnlyDictionary <string, ParameterExpression> parameters) { Check(DepthParameter, parameters); Check(BranchParameter, parameters); var condition = Expression.Equal(Expression.Constant(Name), BranchParameter); // TODO: Negative depth if (MinDepth > 1) { condition = Expression.AndAlso(condition, Expression.LessThanOrEqual(Expression.Constant((byte)MinDepth), DepthParameter)); } if (MaxDepth >= 1) { condition = Expression.AndAlso(condition, Expression.LessThanOrEqual(DepthParameter, Expression.Constant((byte)MaxDepth))); } return(Expression.Condition(condition, Matched?.GetExpression(parameters) ?? Expression.Constant(0f), NotMatched?.GetExpression(parameters) ?? Expression.Constant(0f))); }
private QvxDataRow MakeEntryL(Matched match, QvxTable table) { var row = new QvxDataRow(); row[table.Fields[0]] = match.id; row[table.Fields[1]] = match.calculation_method; row[table.Fields[2]] = match.asset; row[table.Fields[3]] = match.user_id; row[table.Fields[4]] = match.created_at; row[table.Fields[5]] = match.updated_at; row[table.Fields[6]] = match.calculation_started_at; //row[table.Fields[7]] = match.unsold_lots; //row[table.Fields[8]] = match.invalidated_at; //row[table.Fields[0]] = lot.date; //row[table.Fields[1]] = lot.lot_remaining; //row[table.Fields[2]] = lot.total_value; //row[table.Fields[3]] = lot.fee; //row[table.Fields[4]] = lot.fair_value; //row[table.Fields[5]] = lot.id; //row[table.Fields[6]] = lot.gain_type; //row[table.Fields[7]] = lot.amount; //row[table.Fields[8]] = lot.total_sale_value; //row[table.Fields[9]] = lot.value_per_coin; //row[table.Fields[10]] = lot.amount_remaining; //row[table.Fields[11]] = lot.tax_type; //row[table.Fields[12]] = lot.net_gain; //row[table.Fields[13]] = lot.amount_sold; //row[table.Fields[14]] = lot.spot_value; //row[table.Fields[15]] = lot.cost_basis_per_coin; //row[table.Fields[16]] = lot.asset; //row[table.Fields[17]] = lot.date_sold; //row[table.Fields[18]] = lot.sale_value_per_coin; //row[table.Fields[19]] = lot.sale_id; //row[table.Fields[20]] = lot.total_cost_basis; return(row); }
public SubscriptionDelta(Subscription[] expected, Subscription[] actual) { Matched = expected.Intersect(actual).ToArray(); NewSubscriptions = expected.Where(x => !Matched.Contains(x)).ToArray(); ObsoleteSubscriptions = actual.Where(x => !Matched.Contains(x)).ToArray(); }
public Dictionary <string, string> GetFilterDictionary(List <string> values) { Dictionary <string, string> d = new Dictionary <string, string>(); foreach (string s in values) { if (d.ContainsKey(s)) { continue; } if (s == "name") { d.Add("name", Name); } else if (s == "hash") { d.Add("hash", Hash.ToString()); } else if (s == "crc") { d.Add("crc", Crc.ToString()); } else if (s == "type") { d.Add("type", Type); } else if (s == "matched") { d.Add("matched", Matched.ToString()); } else if (s == "valid") { d.Add("valid", Valid.ToString()); } else if (s == "references") { d.Add("references", ReferencesCount.ToString()); } else if (s == "referenced") { d.Add("referenced", ReferencedCount.ToString()); } else if (s == "file") { d.Add("file", Location); } else { foreach (INIParameter p in parameters) { if (p.Name == s) { d.Add(s, p[0].Value); } } } } return(d); }
/// <summary> /// Evaluates the selected <see cref="Rule"/>. /// </summary> /// <remarks> /// Here is where asynchronous becomes. <see cref="Assert"/> and /// <see cref="Report"/> are queued using the <see cref="ThreadPool"/> class. /// <para> /// Nodes matched by this <see cref="Rule"/> are added to the <see cref="EvaluationContextBase.Matched"/> list of /// nodes to skip in the next rule, using the <see cref="IMatchedNodes.AddMatched"/> method. /// This object is a strategy object which implements different algorithms for matching and /// saving node references, as the actual <see cref="XPathNavigator"/> implementation provides /// different methods for accessing the underlying source. /// <para> /// This makes the implementation both performant and compliant with /// the restriction about node mathing (see <link ref="schematron" />) in the spec. /// </para> /// <para> /// <seealso cref="DomMatchedNodes"/> /// <seealso cref="XPathMatchedNodes"/> /// <seealso cref="GenericMatchedNodes"/> /// </para> /// As most of the other evaluation methods, it repositions the /// <see cref="EvaluationContextBase.Source"/> navigator on the root node. /// </para> /// <para>Here is where the multithreading problems arise, which are not /// due to the schema design itself, but this specific evaluation process. /// The intent it to evaluate asserts and reports in parallel, to get the /// most out of the CPU. /// </para> /// </remarks> /// <param name="rule">The <see cref="Rule"/> to evaluate.</param> /// <returns>The messages accumulated by the evaluation of all the child /// <see cref="Assert"/> and <see cref="Report"/>.</returns> /// <exception cref="InvalidOperationException"> /// The rule to evaluate is abstract (see <see cref="Rule.IsAbstract"/>). /// </exception> private string Evaluate(Rule rule) { if (rule.IsAbstract) { throw new InvalidOperationException("The Rule is abstract, so it can't be evaluated."); } StringBuilder sb = new StringBuilder(); Source.MoveToRoot(); XPathNodeIterator nodes = Source.Select(rule.CompiledExpression); ArrayList evaluables = new ArrayList(nodes.Count); while (nodes.MoveNext()) { if (!Matched.IsMatched(nodes.Current)) { // Add the navigator to the list to be evaluated and to // the list of pattern-level nodes matched so far. XPathNavigator curr = nodes.Current.Clone(); evaluables.Add(curr); Matched.AddMatched(curr); } } ArrayList handles = new ArrayList(rule.Asserts.Count + rule.Reports.Count); foreach (Assert asr in rule.Asserts) { //AsyncAssertEvaluate eval = new AsyncAssertEvaluate(EvaluateAssert); foreach (XPathNavigator node in evaluables) { XPathNavigator ctx = node.Clone(); WaitHandle wh = new AutoResetEvent(true); WaitOrTimerCallback cb = new WaitOrTimerCallback(OnAssertEvaluate); ThreadPool.RegisterWaitForSingleObject(wh, cb, new AsyncAssertState(asr, sb, ctx), Timeout.Infinite, true); handles.Add(wh); //handles.Add(eval.BeginInvoke( // asr, ctx, new AsyncCallback(OnAssertCompleted), // new AsyncAssertState(asr, sb, ctx)).AsyncWaitHandle); //Synchronous evaluation //string str = EvaluateAssert(asr, node.Clone()); //if (str != String.Empty) // sb.Append(str).Append(System.Environment.NewLine); } } foreach (Report rpt in rule.Reports) { //AsyncReportEvaluate eval = new AsyncReportEvaluate(EvaluateReport); foreach (XPathNavigator node in evaluables) { XPathNavigator ctx = node.Clone(); WaitHandle wh = new AutoResetEvent(true); WaitOrTimerCallback cb = new WaitOrTimerCallback(OnReportEvaluate); ThreadPool.RegisterWaitForSingleObject(wh, cb, new AsyncReportState(rpt, sb, ctx), Timeout.Infinite, true); handles.Add(wh); //handles.Add(eval.BeginInvoke( // rpt, ctx, new AsyncCallback(OnReportCompleted), // new AsyncReportState(rpt, sb, ctx)).AsyncWaitHandle); //Synchronous evaluation //string str = EvaluateReport(rpt, node.Clone()); //if (str != String.Empty) // sb.Append(str).Append(System.Environment.NewLine); } } try { //TODO: I think we are getting contention here. Anyone can help? WaitHandle[] waithandles = new WaitHandle[handles.Count]; handles.CopyTo(waithandles); WaitHandle.WaitAll(waithandles); } catch (Exception ex) { System.Diagnostics.Debug.Fail(ex.ToString()); } string res = sb.ToString(); return(Formatter.Format(rule, res, Source)); }
public MatchedAssertion <T> EqualToValueOf(Matched <T> otherMatched) { return(add(() => matched.EqualToValueOf(otherMatched), $"Value of $name must $not equal value of {matchedImage(otherMatched)}")); }
/// <summary> /// Adds a trade message /// </summary> /// <param name="msg"></param> public void Add(Matched msg) { _messages.Add(msg); }
public RuleHistory(IEnumerable <Rule> matched, IEnumerable <Rule> activated) : base() { Matched.AddRange(matched); Activated.AddRange(activated); }
public DecisionOptionsHistory(IEnumerable <DecisionOption> matched, IEnumerable <DecisionOption> activated) : base() { Matched.AddRange(matched); Activated.AddRange(activated); }
private void TriggerMatched(T response) { Matched?.Invoke(this, response); }
public static MatchingContext <T> Matching <T>(this Matched <T> matched) => new(matched);
public async static Task <bool> GetMatchedAndNotmachet(ITurnContext turnContext, CancellationToken cancellationToken, IConfiguration config) { turnContext.Activity.Text = turnContext.Activity.Text.Replace(("1qq1_"), ""); string dishName = turnContext.Activity.Text.Substring(0, turnContext.Activity.Text.LastIndexOf("_")); turnContext.Activity.Text = turnContext.Activity.Text.Remove(0, turnContext.Activity.Text.LastIndexOf('_') + 1); IEnumerable <string> ingridients = turnContext.Activity.Text.Split(';').ToList(); List <Matched> MachedList = new List <Matched>(); string Message = ""; Dish dish = new Dish(); var client = new HttpClient(); client.BaseAddress = new Uri(config.GetValue <string>("ConnectionStrings")); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); var danie = client.GetAsync($"/api/recipies/GetDishByName/{dishName}").Result.Content.ReadAsStringAsync(); dish = System.Text.Json.JsonSerializer.Deserialize <Dish>(danie.Result); var nonRepeat = dish.ingridients.Select(x => x.name).Distinct(); List <string> noH2 = new List <string>(); string j = ""; foreach (var i in nonRepeat) { if ((i.Contains("<h2>")) || (i.Contains("</h2>"))) { j = i.Replace("<h2>", ("\n\n**")).Replace("</h2>", ("**\n\n"));; noH2.Add(j); } else { j = i; noH2.Add(j); } } foreach (var item2 in noH2) { foreach (var item3 in ingridients) { if (item3 != "") { Matched matched = new Matched(); if (item2.StartsWith(item3)) { matched.Name = item2; matched.isMatched = true; MachedList.Add(matched); } else { matched.Name = item2; matched.isMatched = false; MachedList.Add(matched); } } } } foreach (var i in MachedList) { if (i.isMatched) { Message += "**" + i.Name + "**\n\n"; } else { Message += i.Name + "\n\n"; } } Attachment imp = new Attachment(); imp.ContentType = "image/png"; imp.ContentUrl = (dish.pictUrl); imp.Name = dish.name; var rep = MessageFactory.Attachment(imp); string listOfIng = string.Join("\n\n", dish.ingridients.Select(p => p.name).Distinct().ToList()); listOfIng = listOfIng.Replace("<h2>", ("\n\n**")).Replace("</h2>", ("**\n\n")); await turnContext.SendActivityAsync(rep); await turnContext.SendActivityAsync((dish.name.ToString() + "\n\n " + "Czas przygotowania: " + dish.timeForPrepare.ToString() + "minut" + "\n" + "\n" + dish.description.ToString().Replace(" ", "") + "\n\n" + Message + "\n \n" + dish.directions1.ToString().Replace("<p style=\"text - align: justify;\">", " ") + "\n\n" + dish.directions2.ToString().Replace("<p style=\"text - align: justify;\">", " ") + "\n\n" + dish.directions3.ToString().Replace("<p style=\"text - align: justify;\">", " ") + "\n\n" + dish.directions4.ToString().Replace("<p style=\"text - align: justify;\">", " "))); return(true); }
/// <summary> /// BoSubst()呼び出し/結果処理簡略化 /// </summary> /// <param name="subst">置換パターン(NULLを指定すると、前回のコンパイル済みパターンを使用する)</param> /// <param name="options">オプション</param> /// <param name="input">検索対象文字列</param> /// <param name="targetstart">検索開始文字位置</param> /// <param name="targetend">検索終了文字位置</param> /// <param name="match">置換対象となるMatchedオブジェクト</param> /// <returns>置換結果文字列(matchが指定されている場合はマッチした部分の変更結果、matchがnullの場合はinput全体の置換結果)</returns> protected string BoSubst( string subst, string options, string input, int targetstart, int targetend, Matched match = null) { if (this.disposed) { throw new ObjectDisposedException("BregonigRegexオブジェクト"); } // 置換オプション/置換パターンが前回と一緒であればコンパイルを省略する string pattern = this.pattern; if (options == this.prevoptions) { pattern = null; options = null; if (subst == this.prevsubst) { subst = null; } else { // subst相違あり、今回指定されたsubstを保存 this.prevsubst = subst; } } else { // option相違あり、今回指定されたoptionsとsubstを保存 this.prevoptions = options; this.prevsubst = subst; } lock (this.pattern) { // 検索位置をポインタに変換 AllocText(input); IntPtr targetstartp = IntPtr.Add(strstartp, targetstart * sizeof(char)); IntPtr targetendp = IntPtr.Add(strstartp, targetend * sizeof(char)); StringBuilder msgSb = new StringBuilder(80); // エラーメッセージ格納用領域を確保 int ret = BoSubst(pattern, subst, options, strstartp, targetstartp, targetendp, null, ref rxp, msgSb); if (ret < 0) { // エラーあり throw new ArgumentException(msgSb.ToString()); } if (ret > 0) { // 置換成功:構造体ポインタの最新の内容を取り出し BREGEXP rx = (BREGEXP)(Marshal.PtrToStructure(rxp, typeof(BREGEXP))); if (match != null) { Group replacedMatch = rx.CreateGroup(0, this); // 置換された部分のマッチ情報を取得 if (match.Index != replacedMatch.Index || match.Length != replacedMatch.Length) { // 検索時/置換時でマッチ箇所が同一にならなかった(通常発生しない。発生したらBregonigRegexのバグ、要究明) throw new SystemException("置換対象のマッチ箇所(Index=" + match.Index + ", Match=" + match.Length + ")" + "とは異なる箇所(Index=" + replacedMatch.Index + ", Match=" + replacedMatch.Length + ")が置換されました。"); } if (rx.outp == null) { return(string.Empty); // 置換結果が空文字となった } // 置換部分の開始位置=置換結果全体の開始位置+(マッチ箇所の開始位置、ただし探索開始位置考慮) IntPtr replacedstart = IntPtr.Add(rx.outp, (match.Index - targetstart) * sizeof(char)); // 置換部分の置換後文字列長=マッチ箇所の置換前文字列長+置換結果全体の文字列長-置換前文字列全体の文字列長 int len = match.Length + (int)((rx.outendp.ToInt64() - rx.outp.ToInt64()) / sizeof(char)) - (targetend - targetstart); // 置換部分の文字列内容のみをピンポイントで抜き出す return(Marshal.PtrToStringUni(replacedstart, len)); } else { // 置換後文字列全体を組み立て StringBuilder sb = new StringBuilder(); if (targetstart > 0) { sb.Append(input.Substring(0, targetstart)); } if (rx.outp != null) { // 空文字列に置換されていなければ、置換結果の文字列を取り出し int len = (int)((rx.outendp.ToInt64() - rx.outp.ToInt64()) / sizeof(char)); sb.Append(Marshal.PtrToStringUni(rx.outp, len)); } if (targetend < input.Length) { sb.Append(input.Substring(targetend)); } return(sb.ToString()); } } else { // 置換箇所なし if (match != null) { // 検索時/置換時でマッチ箇所が同一にならなかった(通常発生しない。発生したらBregonigRegexのバグ、要究明) throw new SystemException("置換対象のマッチ箇所(Index=" + match.Index + ", Match=" + match.Length + ")が検出できませんでした。"); } // 置換前テキスト内容のまま変更なし return(input); } } }