TCL模式匹配(TCL pattern matching)
我是TCL编程的新手。 我想编写一个tcl代码来检查给定字符串中是否有任何模式HAT GET DOT,如果存在,我们应该在给定字符串中显示HAT GET DOT中的哪些模式。 如果字符串中存在多个模式,则应显示所有匹配的模式。 我编写了以下代码,但即使多个模式与给定字符串匹配,它也只显示单个模式。
有人可以帮忙吗?
先谢谢你
码:
set data1 {asdGETdf ferGETfhgDOT} #data1 is the given string foreach index $test_data1 { set result [regexp {ABC|ACC|ADC|AXC} $index match] puts "\n$index" if { $result==1} { puts "MATCH:$match" } else { puts "NO MATCH" } }
output:-asdGETdf MATCH:GET ferGETfhgDOT MATCH:GET
对于第二个字符串,我希望它显示
GET
和DOT
(不像输出那样单独使用GET
)。我认为这是因为一旦找到匹配,regexp就会结束搜索。 但是如何显示所有模式匹配?
I am new to TCL programming. I want to write a tcl code that check if any of the patterns HAT GET DOT present in the given string and if it does, we should display which among the patterns HAT GET DOT is present in the given string. If more than one pattern is present in the string all the matched patterns should be displayed. I wrote the following code, but it only displays a single pattern even if more than one pattern matches the given string.
Can anyone help?
Thank you in advance
Code:
set data1 {asdGETdf ferGETfhgDOT} #data1 is the given string foreach index $test_data1 { set result [regexp {ABC|ACC|ADC|AXC} $index match] puts "\n$index" if { $result==1} { puts "MATCH:$match" } else { puts "NO MATCH" } }
output:-asdGETdf MATCH:GET ferGETfhgDOT MATCH:GET
For the second string I expect it to display
GET
andDOT
(notGET
alone as in the output).I think this is because regexp end the search once a match is found. But how to display all pattern matches?
原文:https://stackoverflow.com/questions/39362032
最满意答案
这对我有用。
首先,将byte []转换为字符串并将字符串拆分为
\r
(Regex Split保留分隔符)。现在有一串字符串,其中一些以
\r
结尾。然后康卡特,以保持他们的秩序。 另外,由于
strings
需要在下一步中变为热点,请发布它们。var strings = bytes. Select(arr => (Regex.Split(Encoding.Default.GetString(arr, 0, arr.Length - 1), "(\r)")). Where(s=> s.Length != 0). ToObservable()). Concat(). Publish(). RefCount();
创建一个字符串窗口,当字符串以
\r
结尾时结束。strings
需要很热,因为它用于Window内容和窗口结束触发器。var linewindows = strings.Window(strings.Where(s => s.EndsWith("\r")));
将每个Window聚合为一个字符串。
var lines = linewindows.SelectMany(w => w.Aggregate((l, r) => l + r));
lines
是IObservable<String>
,每个字符串包含一行。为了测试这个,我使用以下生成器来生成
IObservable<byte[]>
var bytes = Observable. Range(1, 10). SelectMany(i => Observable. Return((byte)('A' + i)). Repeat(24). Concat(Observable. Return((byte)'\r'))). Window(17). SelectMany(w => w.ToArray());
This works for me.
First, Convert the byte[] into a string and Split the string on
\r
(Regex Split keeps the delimiters).Now there is a stream of Strings some of which end in
\r
.Then Concat, to keep them in order. Also, since
strings
needs to be Hot for the next step, Publish them.var strings = bytes. Select(arr => (Regex.Split(Encoding.Default.GetString(arr, 0, arr.Length - 1), "(\r)")). Where(s=> s.Length != 0). ToObservable()). Concat(). Publish(). RefCount();
Make a Window of strings that ends when a string ends with
\r
.strings
needs to be hot since it is used for both the Window contents and the end-of-window trigger.var linewindows = strings.Window(strings.Where(s => s.EndsWith("\r")));
Aggregate each Window into a single string.
var lines = linewindows.SelectMany(w => w.Aggregate((l, r) => l + r));
lines
isIObservable<String>
and each string contains one line.To test this I used the following generator to produce
IObservable<byte[]>
var bytes = Observable. Range(1, 10). SelectMany(i => Observable. Return((byte)('A' + i)). Repeat(24). Concat(Observable. Return((byte)'\r'))). Window(17). SelectMany(w => w.ToArray());
相关问答
更多-
从Stream生成IObservable
的首选方法(Preferred method for generating an IObservable [2023-04-02]from a Stream) 我认为你已经有了一个好主意(将Stream转换为Enumerable,然后将IObservable)。 但是,Enumberable代码可以更清晰: IEnumerableReadLines(Stream stream) { using (StreamReader reader = new StreamReader(stream)) { while (!reader.EndOfStream) yield return reader.R ... -
这很容易。 尝试这个: Bytes .SelectMany(b => b) .Buffer(10) .Select(bs => bs.ToArray()); It's easy. Try this: Bytes .SelectMany(b => b) .Buffer(10) .Select(bs => bs.ToArray());
-
我对NetMQ并不熟悉,但是你真的应该像这样构造你: public static IObservable
Receive(NetMQContext ctx) { return Observable .Create (o => Observable.Using (() => { ... -
Reactive Extensions:从IObservable配对值(Reactive Extensions: Pairing values from an IObservable)[2023-07-16]
BufferWithCount应该有帮助,你可以这样做: var keyPressed = Observable.Create( o => { while (true) { var consoleKeyInfo = Console.ReadKey(true); o.OnNext(consoleKeyInfo.Key); } ... -
首先,返回IObservable来实现异步方法是绝对正确的。 其次,如果是DoApiRequest方法启动通过Messages发出值的进程,则可以在使用CreateWithDisposable调用方法之前先订阅消息 public IObservable
DoAsyncRequest() { return Observable.CreateWithDisposable (observer => { var disposable = ... -
这对我有用。 首先,将byte []转换为字符串并将字符串拆分为\r (Regex Split保留分隔符)。 现在有一串字符串,其中一些以\r结尾。 然后康卡特,以保持他们的秩序。 另外,由于strings需要在下一步中变为热点,请发布它们。 var strings = bytes. Select(arr => (Regex.Split(Encoding.Default.GetString(arr, 0, arr.Length - 1), "(\r)")). Where(s=> s.Length ...
-
GetMyObject().Select(obj => { if (obj?.Count > 5) { return true; } return false; }).AsObservable(); GetMyObject().Select(obj => { if (obj?.Count > 5) { return true; } return false; }).AsObservable();
-
这是因为即使您已经指定了约束, IObservable
和IObservable 之间也没有直接IObservable 。 您应该重新强制转换流中的各个项目: return this.Actions.Where(action => action is T).Cast (); 然后,您的返回值将是正确类型的IObservable。 正如mjwills在注释中指出的那样, IObservable .OfType 的辅助函数存在,它基本上就是为你 ... -
在我看来,这段代码中的基本问题是IObservable 代表了如何观察某事的契约。 在这种情况下, GetObservable方法不只是返回一个契约,而是立即执行工作(使用TPL)。 如果您认为可以多次订阅同一个IObservable实例(实际上是在示例代码中发生,因为您第一次使用Subscribe而另一个Subscribe了Wait ),这没有任何意义。 这个单一的区别是我学习Rx的最大绊脚石。 我会改为实现这样的方法(并避免完全使用Subject<> ,因为它不是创建Observable的首选方法): ...
-
就像在LINQ to Objects中一样,使用投影: var observableB = observableA.Select(a => new B(a)); (显然,根据您的转换进行调整。) 假设我正确理解了这个问题。 “执行第一个观察者的订阅时”的含义并不十分清楚。 Just as you would in LINQ to Objects, use a projection: var observableB = observableA.Select(a => new B(a)); (Obvious ...