没有LookBehind功能的正则表达式

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了没有LookBehind功能的正则表达式相关的知识,希望对你有一定的参考价值。

我正在尝试编写一个查找所有';'的正则表达式未跟随NEW LINE( n)字符的字符。

;(?!\
)

和所有NEW LINE( n)字符前面没有';'字符:

(?< !;)\

不幸的是我使用Qt 4.7.4 QRegExp并且它不支持“Look Behind”。如何重写上面的正则表达式,以便它不使用“Look Behind”?

答案

引用文档:

http://doc.qt.digia.com/4.7/qregexp.html#details

使用与Perl相同的语法支持零宽度正和零宽度负前瞻断言(?=模式)和(?!模式)。

可能发生的是你运行的Windows机器上插入了 而不仅仅是 ...或者它可能是在Windows机器上创建的文本文件。

我需要注意的一件事是,我发现了外观,你不能拥有大多数正则表达式处理程序的可变长度。

如果lookbehinds / lookaheads仍然给你带来麻烦,另一个选择的选项是使用捕获组,然后只引用你感兴趣的捕获组。

从文档的code-examples section它有这个:

str = "Nokia Corporation	qt.nokia.com	Norway";
QString company, web, country;
rx.setPattern("^([^	]+)	([^	]+)	([^	]+)$");
if (rx.indexIn(str) != -1) {
    company = rx.cap(1);
    web = rx.cap(2);
    country = rx.cap(3);
}

捕获组使用括号定义,稍后通过其索引从1开始访问。第0个索引是整个匹配(不分为捕获组)。

http://doc.qt.digia.com/4.7/qregexp.html#cap

http://doc.qt.digia.com/4.7/qregexp.html#capturedTexts

希望有所帮助。正常表达在工作正常时会很有趣。祝好运。

我也喜欢使用这个tool。格式可能与QRegEx略有不同,但是一旦你拥有它就可以很快地进行翻译和测试。

更新:这是一个完整的套件,展示4个不同的捕获字符串以及他们在QRegEx中找到的内容:

#include <QCoreApplication>
#include <QRegExp>
#include <QString>
#include <QDebug>
#include <QStringList>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QString str =
            "This is a long string;
"
            "with some semi colons;
"
            "sometimes followed by a new line;
"
            "and other times followed; by something else.
"

            "(;)([^\n]) find a semicolon and a new line
"
            "(;)(?!\n)  find a semicolon not followed by a new line, negative look-ahead
"

            "([^;])(\n) find a non semicolon and a new line
"
            "(?<!;)(\n) find a new line, not preceeded by a semicolon.
";

    QList <QRegExp> rx_list;

    QRegExp rx_colon_and_non_newline;
    rx_colon_and_non_newline.setPattern("(;)([^\n])");

    QRegExp rx_colon_and_neg_lookahead;
    rx_colon_and_neg_lookahead.setPattern("(;)(?!\n)");

    QRegExp rx_non_colon_and_newline;
    rx_non_colon_and_newline.setPattern("([^;])(\n)");

    QRegExp rx_neg_lookbehind_and_newline;
    rx_neg_lookbehind_and_newline.setPattern("(?<!;)(\n)");

    rx_list << rx_colon_and_non_newline
            << rx_colon_and_neg_lookahead
            << rx_non_colon_and_newline
            << rx_neg_lookbehind_and_newline;

    foreach(QRegExp rx, rx_list)
    {
        int count = 0;
        int pos = 0;
        qDebug() << "Pattern" << rx.pattern();
        while ((pos = rx.indexIn(str, pos)) != -1) {
            QStringList capturedTexts(rx.capturedTexts());

            for(int i = 0; i<capturedTexts.size(); i++)
                capturedTexts[i].replace('
',"\n");

            qDebug() << "	" << count << "Found at position" << pos << capturedTexts;
            // qDebug() << rx.cap();
            pos += rx.matchedLength();
            ++count;
        }
        if(count == 0)
            qDebug() << "	No matches found.";
    }


    return a.exec();
}

输出:

Pattern "(;)([^
])"
         0 Found at position 104 ("; ", ";", " ")
         1 Found at position 126 (";)", ";", ")")
         2 Found at position 169 (";)", ";", ")")
         3 Found at position 247 (";]", ";", "]")
         4 Found at position 295 (";)", ";", ")")
Pattern "(;)(?!
)"
         0 Found at position 104 (";", ";")
         1 Found at position 126 (";", ";")
         2 Found at position 169 (";", ";")
         3 Found at position 247 (";", ";")
         4 Found at position 295 (";", ";")
Pattern "([^;])(
)"
         0 Found at position 123 (".
", ".", "
")
         1 Found at position 166 ("e
", "e", "
")
         2 Found at position 242 ("d
", "d", "
")
         3 Found at position 289 ("e
", "e", "
")
         4 Found at position 347 (".
", ".", "
")
Pattern "(?<!;)(
)"
        No matches found.
另一答案

Perl的lookbehind断言,“独立”子表达式和条件表达式不受支持。

来自http://doc.qt.io/archives/qt-4.8/qregexp.html

所以(?<;!;) 不起作用 并且(?!;) 将匹配所有新行字符 无论他们之前是否有;

以上是关于没有LookBehind功能的正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

ES2018 新特征之:正则表达式反向(lookbehind)断言

正则表达式的可变长度lookbehind-assertion替代方案

R 正则表达式 Lookbehind

如何测试以确定浏览器是不是支持 JS 正则表达式lookahead/lookbehind?

将lookbehind模式与匹配的正则表达式搜索模式分组以作为整体替换

如何使用带有线锚的 C# 正则表达式 Lookbehind