使用正则表达式检测类似"#smth"的文本(带有更多术语)

Detecting text like "#smth" with RegExp (with some more terms)

本文关键字:术语 文本 正则表达式 检测 #smth      更新时间:2023-10-16

我在正则表达式方面真的很糟糕,所以请帮助我。

我需要在字符串中找到任何像#text这样的作品.

text不得包含任何空格字符 ( \s )。它的长度必须至少为 2 个字符 ( {2,} ),并且必须包含至少 1 个字母 ( QChar::isLetter() )。

例子:

  • #c#1#123456#123 456#123_456不正确
  • #cc#text#text123#123text是正确的

我使用 QRegExp。

QRegExp rx("#(\S+[A-Za-z]\S*|\S*[A-Za-z]\S+)$");
bool result = (rx.indexIn(str) == 0);
Rx 要么找到后

跟一个字母和未指定数量的非空格字符的非空格,要么找到一个字母后跟至少非空格。

Styne666给出了正确的正则表达式。

这里有一个小的Perl脚本,它试图将其第一个参数与此正则表达式匹配:

    #!/usr/bin/env perl
    use strict;
    use warnings;
    my $arg = shift;
    if ($arg =~ m/(#(?=d*[a-zA-Z])[a-zA-Zd]{2,})/) {
        print "$1 MATCHES THE PATTERN!n";
    } else {
        print "NO MATCHn";
    }

Perl 总是非常适合快速测试你的正则表达式。

现在,你的问题有点不同。您想在文本字符串中找到所有子字符串,你想在C++/Qt中做到这一点。这是我可以在几分钟内想到的:

    #include <QtCore/QCoreApplication>
    #include <QRegExp>
    #include <iostream>
    using namespace std;
    int main(int argc, char *argv[])
    {
        QString str = argv[1];
        QRegExp rx("[\s]?(\#(?=\d*[a-zA-Z])[a-zA-Z\d]{2,})\b");
        int pos = 0;
        while ((pos = rx.indexIn(str, pos)) != -1)
        {
            QString token = rx.cap(1);
            cout << token.toStdString().c_str() << endl;
            pos += rx.matchedLength();
        }
        return 0;
    }

为了使我的测试,我给它一个这样的输入(使长字符串只有一个命令行参数):

    peter@ubuntu01$ qt-regexp "#hjhj  4324   fdsafdsa  #33e #22"

它只匹配两个词:#hjhj#33e

希望对您有所帮助。

我能想出的最短的(应该有效,但我还没有广泛测试)是:

QRegExp("^#(?=[0-9]*[A-Za-z])[A-Za-z0-9]{2,}$");

哪些匹配:

  • ^字符串的开头
  • #文字哈希字符
  • (?=然后向前看(但不匹配)
    • [0-9]*零个或多个拉丁数字
    • [A-Za-z]单个大写或小写拉丁字母
  • )
  • 然后[A-Za-z0-9]{2,}匹配至少两个字符,可以是大写或小写拉丁字母或拉丁数字
  • 然后$查找并使用行尾

从技术上讲,这仍然是错误的。它只匹配拉丁字母和数字。替换几个位可以为您提供:

QRegExp("^#(?=\d*[^\d\s])\w{2,}$");

这应该适用于非拉丁字母和数字,但这完全未经测试。快速阅读 QRegExp 类参考,了解每个转义组的说明。

然后在较大的文本字符串中匹配(同样,未经测试):

QRegExp("b#(?=\d*[^\d\s])\w{2,}b");

一个有用的工具是SDK附带的正则表达式示例。

使用此正则表达式。 希望您的问题能用给定的 RE 解决。

^([#(a-zA-Z)]+[(a-zA-Z0-9)]+)*(#[0-9]+[(a-zA-Z)]+[(a-zA-Z0-9)]*)*$