社区首页 >问答首页 >如何为提到和哈希标签修复这个正则表达式?

如何为提到和哈希标签修复这个正则表达式?
EN

Stack Overflow用户
提问于 2018-03-15 11:56:36
回答 3查看 1.4K关注 0票数 3

我使用下面的工具为提到和哈希标签构建了一个有效的regex。我已经成功地匹配了插入文本中我想要的内容,但我需要解决以下匹配问题。

  • 只匹配以空格开头和结尾的子字符串。如果是在字符串的开头或结尾处的子字符串是有效的(无论是hashtag还是提到),也可以使用它。
  • regex找到的匹配只包含不包含空格的部分(空格只是规则的一部分,而不是子字符串的一部分)。

我使用的正则表达式如下:(([@]{1}|[#]{1})[A-Za-z0-9]+)

字符串匹配的有效性和不有效性的一些示例:

代码语言:javascript
代码运行次数:0
复制
"@hello friend" - @hello must be matched as a mention.
"@ hello friend" - here there should be no matches.
"hey@hello @hello" - here only the last @hello must be matched as a mention.
"@hello! hi @hello #hi ##hello" - here only the second @hello and #hi must be matched as a mention and hashtag respectively.

图像中的另一个例子,其中只应该提到"@word"

更新16:35 (格林尼治时间-4) 3/15/18

我找到了解决这个问题的方法,在PCRE模式(服务器)中使用工具,并使用negative lookbehindnegative lookahead

代码语言:javascript
代码运行次数:0
复制
(?<![^\s])(([@]{1}|[#]{1})[A-Za-z0-9]+)(?![^\s])

这是火柴:

但现在出现了疑问,它适用于C#?中的正则表达式,包括negative lookaheadnegative lookbehind,因为在Javascript中它不能工作,就像在工具中看到的那样,它用红线标记我。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-15 12:14:33

尝试以下模式:

代码语言:javascript
代码运行次数:0
复制
(?:^|\s+)(?:(?<mention>@)|(?<hash>#))(?<item>\w+)(?=\s+)

在这里,它被细分为:

  • (?:创建一个非捕获组。
  • ^|\s+匹配字符串或空格的开头
  • (?:创建一个非捕获组。
  • (?<mention>@|(?<hash>#)创建一个与@#匹配的组,并分别将组命名为“提到”和“哈希”。
  • (?<item>\w+)匹配任何字母数字字符一次或多次,并帮助从组中提取项目以便于使用。
  • (?=\s+)创建了一个积极的前景,以匹配任何空白。

小提琴:现场演示

然后,您需要使用底层语言来修剪返回的匹配,以删除任何前导/尾随空格。

Update由于您提到您使用的是C#,所以我想我会为您提供一个.NET解决方案来解决不需要RegEx的问题;虽然我没有测试结果,但我想这也比使用RegEx更快。

就我个人而言,我对.NET的兴趣是Visual,所以我为您提供了一个VB.NET解决方案,但是您也可以通过转换器轻松地运行它,因为我从不使用C#中不能使用的东西:

代码语言:javascript
代码运行次数:0
复制
Private Function FindTags(ByVal lead As Char, ByVal source As String) As String()
    Dim matches As List(Of String) = New List(Of String)
    Dim current_index As Integer = 0

    'Loop through all but the last character in the source
    For index As Integer = 0 To source.Length - 2
        'Reset the current index
        current_index = index

        'Check if the current character is a "@" or "#" and either we're starting at the beginning of the String or the last character was whitespace and then if the next character is a letter, digit, or end of the String
        If source(index) = lead AndAlso (index = 0 OrElse Char.IsWhiteSpace(source, index - 1)) AndAlso (Char.IsLetterOrDigit(source, index + 1) OrElse index + 1 = source.Length - 1) Then
            'Loop until the next character is no longer a letter or digit
            Do
                current_index += 1
            Loop While current_index + 1 < source.Length AndAlso Char.IsLetterOrDigit(source, current_index + 1)

            'Check if we're at the end of the line or the next character is whitespace
            If current_index = source.Length - 1 OrElse Char.IsWhiteSpace(source, current_index + 1) Then
                'Add the match to the collection
                matches.Add(source.Substring(index, current_index + 1 - index))
            End If
        End If
    Next

    Return matches.ToArray()
End Function

小提琴:现场演示

票数 2
EN

Stack Overflow用户

发布于 2018-03-15 12:07:52

您可以在现有regex周围使用或空格作为行的开始/结束。

^-开始

$ end

S-空间

代码语言:javascript
代码运行次数:0
复制
(^|\s+)(([@]{1}|[#]{1})[A-Za-z0-9]+)(\s+|$)
票数 1
EN

Stack Overflow用户

发布于 2018-03-15 12:30:46

这个regex可以帮你做这件事。

代码语言:javascript
代码运行次数:0
复制
[@#][A-Za-z0-9]+\s|\s[@#][A-Za-z0-9]+

运算符\负责创建一个逻辑“或”,因此您需要匹配两个不同的表达式。

代码语言:javascript
代码运行次数:0
复制
[@#][A-Za-z0-9]+\s

代码语言:javascript
代码运行次数:0
复制
\s[@#][A-Za-z0-9]+

哪里

代码语言:javascript
代码运行次数:0
复制
\s - space
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49308174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文