如何修复这个正则表达式提及和标签?

时间:2018-03-15 19:56:37

标签: c# android regex string regex-group

我使用以下tool为提及和主题标签构建有效的regex。我已经设法匹配插入文本中我想要的内容,但我需要解决以下匹配问题。

  
      
  • 仅匹配以空格开头和结尾的子字符串。并且在字符串的开头或结尾处有子字符串的情况下   这是有效的(无论是标签还是提及),也可以接受它。

  •   
  • 正则表达式找到的匹配只占用不包含空格的部分,(空格只是规则的一部分,但不是   子串的一部分)。

  •   

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

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

"@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"应该是有效的提及:

enter image description here

更新16:35(GMT-4)3/15/18

我找到了一种解决问题的方法,使用PCRE模式中的tool(服务器)并使用negative lookbehindnegative lookahead

(?<![^\s])(([@]{1}|[#]{1})[A-Za-z0-9]+)(?![^\s])

以下是比赛:

enter image description here

但是现在出现了疑问,它适用于C#中的正则表达式,negative lookaheadnegative lookbehind,因为例如在Javascript中它不起作用,因为它在工具中看到它,它用红线标记我。

3 个答案:

答案 0 :(得分:1)

您可以在现有正则表达式周围添加一个或以及为空格的行的开头/结尾。

^ - 开始

$ - 结束

\ s - 空间

(^|\s+)(([@]{1}|[#]{1})[A-Za-z0-9]+)(\s+|$)

答案 1 :(得分:1)

尝试这种模式:

(?:^|\s+)(?:(?<mention>@)|(?<hash>#))\w+(?=\s+)

这里分解了:

  • (?:创建一个非捕获组
  • ^|\s+匹配字符串或空格的开头
  • (?:创建一个非捕获组
  • (?<mention>@|(?<hash>#)创建一个匹配@#的组,并分别命名提及群组
  • \w+一次或多次匹配任何字母数字字符
  • (?=\s+)创造了一个积极的向前看,以匹配任何空白

小提琴:Live Demo

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

<强>更新 既然你提到你使用的是C#,我认为我会为你提供一个.NET解决方案来解决你不需要RegEx的问题;虽然我没有测试结果,但我猜这也会比使用RegEx更快。

就个人而言,我的.NET风格是Visual Basic,所以我为你提供了一个VB.NET解决方案,但你可以轻松地通过转换器运行它,因为我从来没有使用任何不能用于C#:

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

小提琴:Live Demo

答案 2 :(得分:0)

这个正则表达式可以帮到你。

[@#][A-Za-z0-9]+\s|\s[@#][A-Za-z0-9]+

运营商 | 负责制作逻辑&#34;或&#34;,因此您有2个不同的表达式可供匹配。

[@#][A-Za-z0-9]+\s

\s[@#][A-Za-z0-9]+

,其中

\s - space