C# 从设备名称中提取模型

C# 从设备名称中提取模型,c#,regex,C#,Regex,Mozilla/2.0(Linux;Android 2.0;KK;三星SM-G900H Build/LRX21T)AppleWebKit 需要提取三星SM-G900H Build/LRX21T Mozilla/5.0(Linux;Android 5.0;三星SM-G900H Build/LRX21T)AppleWebKit 需要提取三星SM-G900H Build/LRX21T Mozilla/5.0(Linux;Android 5.1;XT1032构建/LPBS23.13-56-2;wv)Ap

Mozilla/2.0(Linux;Android 2.0;KK;三星SM-G900H Build/LRX21T)AppleWebKit

需要提取三星SM-G900H Build/LRX21T

Mozilla/5.0(Linux;Android 5.0;三星SM-G900H Build/LRX21T)AppleWebKit

需要提取三星SM-G900H Build/LRX21T

Mozilla/5.0(Linux;Android 5.1;XT1032构建/LPBS23.13-56-2;wv)AppleWebKit

需要提取
XT1032构建/LPBS23.13-56-2

逻辑是:

1. Take first [(.....)]
2. Take text after last semicolon [;]
3. Or take text after last semicolon [;] and before [; wv]
我现在所拥有的:

*?\(*;(?*?)(;wv)?\)


但这适用于前两个示例,对于第三个示例,它返回
wv

仅在分号上拆分为一个数组:

string[] parts = myUserAgent.Split(";");
现在您可以通过以下方式获得“三星…”

最后,使用“替换”功能删除无意中的字符。

这样做如何:

;\s*(?<model>([^;)])*)
虽然是部分,但您似乎并不需要该部分。

^(.*)\(.*;(?(?!(wv))[^;()]*(\(.??\)?[^;)]*)+(;??)\)*$
^(.*)\(.*;(?<model>(?!( wv))[^;()]*(\(.??\))?[^;)]*)+?(;.*)?\).*$
火柴

  • Mozilla/5.0(Linux;Android 5.1;XT1032构建/LPBS23.13-56-2;wv)AppleWebKit
  • Mozilla/5.0(Linux;Android 5.0;三星SM-G900H Build/LRX21T)AppleWebKit
  • Mozilla/5.0(Linux;Android 5.0;SAMSUNG SM-G900H Build/LRX21T)AppleWebKit/537.36(KHTML,类似Gecko)SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36
  • Mozilla/5.0(Linux;Android 6.0.1;Moto G(4)Build/MPJ24.139-23.1)AppleWebKit/537.36(KHTML,类似Gecko)Chrome/64.0.3282.137 Mobile Safari/537.36
消极的前瞻(
(?!wv)
)为我创造了它

我想您仍然可以使表达式更加精简,但是这个表达式首先应该适合(与/gi标志[global,不区分大小写]一起使用)

使其工作的重要事项:

  • 负前瞻(?!…)
  • 惰性量词??(第二个“?”表示 (这是懒惰,不是贪婪)
编辑:添加了匹配组中不能包含“')”的条件
EDIT2:修改表达式使其适合更多字符串

谢谢,但我知道如何拆分字符串。问题是关于正则表达式的解决方案。您是否只想使用正则表达式?或者使用其他逻辑很好?我有一种感觉,没有正则表达式更容易实现(假设您的模型名中可能有“()”)@Evk,是的,这是不幸的。
Mozilla/5.0(Linux;Android 5.0.2;MotoE2(4G-LTE)Build/LXI22.50-53.8;wv)AppleWebKit/537.36(KHTML,像Gecko)Version/4.0 Chrome/45.0.2454.95 Mobile Safari/537.36
您可能可以使用regex中特定于.NET的平衡组功能来实现这一点,但我不明白为什么要这么麻烦。它是有效的,但问题是,当它返回多个匹配时,找出我需要哪一个匹配是一个问题。但是,谢谢!它不应该总是相同的匹配吗,因为唯一改变的是wv?:)这并不不幸,因为这只是一个例子,还有很多其他格式。例如
Opera/9.80(Android;Opera-Mini/16.0.2168/88.150;U;es)Presto/2.12.423 Version/12.16
。问题是这种匹配是在SQL Server的CLR函数中完成的
[dbo].[DeviceExtractor](@input NVARCHAR(最大值),@pattern NVARCHAR(最大值))
我需要所有类型的模式都相同。不要硬编码匹配索引,因为不同的模式会有所不同。如果您不知道附件列表中的哪一项是设备名,您就有问题。因为这要求您能够检测设备名(我想这就是你想要的):(你能检查一下为什么它不适用于这个
Mozilla/5.0(Linux;Android 5.0;三星SM-G900H Build/LRX21T)AppleWebKit/537.36(KHTML,像Gecko一样)SamsungBrowser/4.0 Chrome/44.0.2403.133 Mobile Safari/537.36
@GiorgiNakeuri我对其进行了修改,使其与您的较长版本相匹配。但是,如果它包含“')(如果存在的话)则与您的设备名称不再匹配!谢谢。我还注意到可能有类似的子版本:
Mozilla/5.0(Linux;Android 6.0.1;Moto G(4)Build/MPJ24.139-23.1)AppleWebKit/537.36(KHTML,类似Gecko)Chrome/64.0.3282.137 Mobile Safari/537.36
。它提取了Moto G(4 。我想这将是很难考虑的。如果你也想这样,恐怕你需要使用递归正则表达式。你可以看到这个问题,但是我现在不能用这个特性来编辑我的答案,我需要在晚上(我在工作中)做它。你需要允许‘(’和‘)’。只要他们的人数相等,好的,我理解。谢谢!
Mozilla/5.0 (Linux
^(.*)\(.*;(?<model>(?!( wv))[^;()]*(\(.??\))?[^;)]*)+?(;.*)?\).*$