Добрый день.
Когда-то был реализовал поиск текста по справке. Пользовался регулярными (QRegExp) выражениями:
QRegExp("\\bтекст\\b") для поиска типа "только слова целиком";
QRegExp("текст") если не учитывая слова целиком.
Чтобы учитывать регистр использовал метод QRegExp::setCaseSensitivity(Qt::CaseSensitivity cs).
Поиск по тексту проводил методом QString::count(const QRegularExpression &re) const.
На днях заметил, что текст типа "(текст" или "текст)" моя программа не находит. В то же время, текст типа "(текст)" находит.
Регулярные выражения использовал лишь из-за того, чтобы можно было искать текст учитывая поиск "только слова целиком".
Понимаю, что проблема в регулярном выражении. Но вот понять как правильно составить регулярное выражение для поиска всевозможного
текста не могу понять.
Ниже прикрепляю небольшой пример. Может кто-то уже решал подобную проблему. Буду рад любым советам.
Исходники программы:FindSubstring.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = FindSubstring
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
void changeEvent(QEvent *e);
public slots:
void substring_search();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->source_text->setFont(QFont("Times New Roman", 12, QFont::Normal));
ui->source_text->setText("Беспилотный летательный аппарат (БЛА, БПЛА; в разговорной речи также «беспилотник» или «дрон», от англ. drone — трутень) — "
"летательный аппарат без экипажа на борту."
"БПЛА могут обладать разной степенью автономности — от управляемых дистанционно до полностью автоматических, а также различаться "
"по конструкции, назначению и множеству других параметров. Управление БПЛА может осуществляться эпизодической подачей команд или "
"непрерывно — в последнем случае БПЛА называют дистанционно-пилотируемым летательным аппаратом (ДПЛА). БПЛА могут решать разведывательные "
"задачи (на сегодня это основное их предназначение), применяться для нанесения ударов по наземным и морским целям, перехвата воздушных целей, "
"осуществлять постановку радиопомех, управления огнём и целеуказания, ретрансляции сообщений и данных, доставки грузов.");
QFont standart_font(QFont("Arial", 9, QFont::Normal));
ui->case_sensitive_ch->setFont(standart_font);
ui->whole_words_ch->setFont(standart_font);
ui->find_but->setFont(standart_font);
ui->result_find_lb->setFont(standart_font);
ui->find_edit->setFont(standart_font);
connect(ui->find_but, SIGNAL(clicked(bool)), this, SLOT(substring_search()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::changeEvent(QEvent *e)
{
QMainWindow::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}
void MainWindow::substring_search()
{
ui->result_find_lb->setText("");
if(ui->find_edit->text() == "")
{
ui->result_find_lb->setText("Введите текст для поиска!");
}
else
{
QString find_text;
if(ui->whole_words_ch->isChecked() == true)
find_text = QString("\\b%1\\b").arg(ui->find_edit->text());
else
find_text = QString("%1").arg(ui->find_edit->text());
QRegExp reg_find_text(find_text);
if(ui->case_sensitive_ch->isChecked() == true)
reg_find_text.setCaseSensitivity(Qt::CaseSensitive);
else
reg_find_text.setCaseSensitivity(Qt::CaseInsensitive);
reg_find_text.setMinimal(true);
int count_find = ui->source_text->document()->toPlainText().count(reg_find_text);
if(count_find == 0)
ui->result_find_lb->setText("В данном тексте нет такой подстроки.");
else
ui->result_find_lb->setText(QString("В данном тексте введенная вами строка "
"встречается %1 раз.").arg(count_find));
}
}
Скрин програмки и архив:
потому что скобка — это спецсимвол регулярок (один из), обозначающий «захватывающую группу». скобки должны быть сбалансированы для того, чтобы регулярка была валидная.
для включения литеральной скобки (и прочих особых символов) в искомое выражение, необходимо ее экранировать с помощью обратной косой черты: \(. (в С++ строке саму обратную косую черту также надо экранировать: "\\(")
чтобы не возиться с ручным экранированием, есть удобный метод QRegularExpression::escape(): https://doc.qt.io/qt-5/qregularexpression.html#escape
kambala, благодарю за ответ.