提问人:Espada 提问时间:10/10/2023 最后编辑:InSyncEspada 更新时间:10/10/2023 访问量:158
正则表达式,在 char 之前获取 char
Regex, get char after char before char
问:
样本:
[Foo][Bar]Foo bar foo bar: foo; bar: foo bar foo bar __ [Foo][Bar]Foo; bar: foo bar __ foo bar foo bar [Foo]Foo bar foo bar foo bar: foo __ bar; foo bar __ foo bar [Bar]Foo; bar; foo
例如,我有一个如上所示的字符串格式。
我想问的是,如何获取分号(不是空格或空格)之后的字母,而是第一个冒号之前的字母?;
:
如果可能的话,我想使用正则表达式一步标记字母
我想得到的字母以粗体标记
*作为附加信息,我想将字母更改为大写。
答:
0赞
Ted Lyngmo
10/10/2023
#1
^[^;:]*;\s*(.).*:
^
- 线锚点的起点[^;:]*
- 匹配除零次或多次之外的任何东西;
:
;
- 在文字上匹配;
\s*
- 零个或多个空格的匹配(.)
- 捕获一个角色.*
- 在任何字符上匹配零次或多次:
- 匹配文字冒号
既然你也说你想要并被捕获,那么实际上似乎不需要冒号。b
f
[Bar]Foo; bar; foo
这是一个将捕获和:b
f
^(?:[^;:]*;\s*(.))+
^
- 线锚点的起点(?:
- 非捕获组的开始[^;:]*
- 匹配任何字符,但零次或更多次;
:
;
- 在文字上匹配;
\s*
- 在空格上匹配零次或更多次(.)
- 捕获一个角色。如果不允许将其替换为([^:])
:
)
- 非捕获组结束+
- 匹配非捕获组 1 次或更多次
评论
0赞
Espada
10/10/2023
我已经尝试了您的代码,但正如我所说,我想在分号之后但在第一个冒号之前获得 1 个字母或 1 个单词(无关紧要)。第一个冒号后面的分号不包括在内,也不考虑在内。
0赞
Ted Lyngmo
10/10/2023
@Espada好的,如果我理解正确,更新应该可以工作。在示例字符串中,只有第二行有一个匹配项。
0赞
Jotne
10/10/2023
我猜 OP 会想要 how 这个词,不仅仅是一个字母,而是字母
0赞
Ted Lyngmo
10/10/2023
@Jotne这是我的第一个想法,但OP不在乎它只是一个字母还是一个单词。请参阅此处的第一条评论。此外,在 OP 的原始版本中,它只捕获了一个字母。
0赞
Jotne
10/10/2023
好的,但是这一行中也有一个粗体 B,但没有 :,所以不确定什么是正确的。[Bar]Foo; bar; foo
1赞
InSync
10/10/2023
#2
使用两个环视从要匹配的字符中排除周围环境:
(?<= # Match something preceded by
^[^:]*;\s* # the start of the line, 0 or more non-colons, a semicolon and any whitespaces
) # that is
[^\s:] # not a colon and not a whitespace
(?= # which must be followed by
[^:]*(?:$|:) # 0 or more non-colons, then either the end of the line or the first colon.
) #
[^:]
, , 并且从不匹配冒号,因此 lookahead 中的冒号与该行的第一个冒号匹配。如果没有冒号,我们只需回退到行尾,从而允许主表达式匹配。;
\s
[^\s:]
正则表达式需要具有多行修饰符 (/)。我不知道 VB.NET,但以下片段似乎有效:(?m)
RegexOptions.Multiline
Sub Main()
Dim regex As New Regex("(?<=^[^:]*;\s*)[^\s:](?=[^:]*(?:$|:))", RegexOptions.Multiline)
Dim input As String =
"[Foo][Bar]Foo bar foo bar: foo; bar: foo bar foo bar __" & vbCrlf &
"[Foo][Bar]Foo; bar: foo bar __ foo bar foo bar" & vbCrlf &
"[Foo]Foo bar foo bar foo bar: foo __ bar; foo bar __ foo bar" & vbCrlf &
"[Bar]Foo; bar; foo"
Console.WriteLine(regex.Replace(input, AddressOf ConvertToUppercase))
End Sub
Function ConvertToUppercase(match As Match) As String
Return match.Groups(0).Value.ToUpper()
End Function
评论
0赞
InSync
10/10/2023
在撰写本文时,regex101.com 向大多数请求返回 504,因此可能无法访问该链接。
0赞
Ted Lyngmo
10/10/2023
不过,我手动输入了您的内容,它似乎捕获了与 OP 给出的示例相同的内容。+1(?<=^[^:]*;\s*)[^\s:](?=[^:]*(?:$|:))
^(?:[^;:]*;\s*(.))+
0赞
InSync
10/10/2023
@TedLyngmo谢谢。老实说,我确实认为我的更适合替换,因此更适合 OP 的目标,即将这些字符替换为大写版本。
0赞
Ted Lyngmo
10/10/2023
不知道。所有以一种或另一种方式工作的替代方案都是好的 - 也许这其中有一个微妙的区别,对 OP 更有效。我认为最好使用常规 VB 函数将它们大写。我在 .net 正则表达式引擎中找不到任何可以自动执行此操作的东西,但也许它在某个地方。
0赞
Espada
10/10/2023
@InSync 经过 2 天的寻找,终于......正则表达式和 vb.net 代码运行良好,正如我所期望的那样。非常感谢:-)
评论
;\s*(\w)(?=.*:)
bar:
b
f
[Bar]Foo; bar; foo