2017-08-08 25 views
0

C++アプリケーションで正規表現を実行するためにQtを使用しようとしています。 以前はC++でQtと同様の正規表現を行ってきましたが、これは難しいことが分かりました。QRegExpでC++で文字列の一部を取り込む

文字列の末尾にオプションの_#を付けた文字列を指定すると、その前に文字列の一部を抽出します。

例:

"blue_dog" should result "blue_dog" 
"blue_dog_1" should result "blue_dog" 
"blue_dog_23" should result "blue_dog" 

これは私がこれまで持っているが、それはまだ動作しないコードです:

QString name = "blue_dog_23"; 
QRegExp rx("(.*?)(_\\d+)?");  
rx.indexIn(name); 
QString result = rx.cap(1); 

私も運なしで多くのバリエーションで、次の追加オプションを試してみました。上のコードは常に「」と表示されます。

rx.setMinimal(TRUE); 
rx.setPatternSyntax(QRegExp::RegExp2); 

答えて

1

時にはそれが簡単だとのすべてをパックしません単一の正規表現あなたのケースでは、既存の_#サフィックスの場合に操作を制限することができそうでなければ結果はnameです。また

QString name = "blue_dog_23"; 
QRegExp rx("^(.*)(_\\d+)$"); 
QString result = name; 
if (rx.indexIn(name) == 0) 
    result = rx.cap(1); 

、あなたが最後のビットを分割することができますし、それが数値であるかどうかを確認A。コンパクトですが(おそらく最も読みにくい)解決策:

QString name = "blue_dog_23"; 
int i = name.lastIndexOf('_'); 
bool isInt = false; 
QString result = (i >= 0 && (name.mid(i+1).toInt(&isInt) || isInt)) ? name.left(i) : name; 
+0

素晴らしい作品です!ありがとうTim。 – panofish

0

次の解決方法は、必要に応じて機能するはずです。

^[^\s](?:(?!_\d*\n).)*/gm

基本的には、それは、まですべてを一致させると言ったが、含めない、_\d*\nれます。ここでは、_\d*\n_の文字と一致し、次に\d*の任意の桁数を、新しいラインマーカー\nに達するまで一致させることを意味します。 ?!は否定先読みであり、?:は非キャプチャグループです。基本的には、この組み合わせは、?:の後のシーケンスが、キャプチャされるべきものの非包含的エンドポイントを表すグループであることを意味する。

^[^\s]は、最初の文字が空白でない限り、行の先頭から一致するように式に指示します。

/gmは、シーケンスは、単一のラインを超えて一致させることができますグローバルフラグ(複数の一致が返されることを可能にする)とmutliラインフラグを(設定します。

関連する問題