1

以下の「クエリ」という名前のファイルからテーブル名と列名を見つけたいです。

var query = "  SELECT accounts.name, SUM((COALESCE((jan_val_c),0)+  ";
query += "  COALESCE((feb_val_c),0)+ COALESCE((march_val_c),0)+ COALESCE((apr_val_c),0)+ ";
query += "  COALESCE((may_val_c),0)+ COALESCE((june_val_c),0)+ COALESCE((july_val_c),0)+   ";
query += "  COALESCE((aug_val_c),0)+ COALESCE((sept_val_c),0)+ COALESCE((oct_val_c),0)+   ";
query += "  COALESCE((nov_val_c),0)+ COALESCE((dec_val_c),0))) AS sales_plan,SUM((COALESCE((jan_actual_val_c),0)+   ";
query += "  COALESCE( (feb_actual_val_c),0)+ COALESCE( (march_actual_val_c),0)+ COALESCE( (apr_actual_val_c),0)+   ";
query += "  COALESCE( (may_actual_val_c),0)+ COALESCE( (june_actual_val_c),0)+ COALESCE( (july_actual_val_c),0)+   ";
query += "  COALESCE( (aug_actual_val_c),0)+ COALESCE( (sept_actual_val_c),0)+ COALESCE( (oct_actual_val_c),0)+   ";
query += "  COALESCE( (nov_actual_val_c),0)+ COALESCE( (dec_actual_val_c),0))) AS Actual_plan ,month_name_c,  ";
query += "   cl_sales_planning_month.year_c, cl_products.volume,cl_brands.name AS brand ,cl_therapies.name   ";
query += "   AS therapy,cl_products.name AS product, accounts.created_by,accounts.assigned_user_id ,   ";
query += "   DATE_FORMAT(STR_TO_DATE(CONCAT_WS('-',cl_sales_planning_month.month_name_c,  ";
query += "   cl_sales_planning_month.year_c),'%M-%Y'),'%b-%y' ) AS monthyear FROM cl_sales_planning_month   ";
query += "   LEFT JOIN accounts ON cl_sales_planning_month.account_id_c =accounts.id LEFT JOIN cl_products   ";
query += "   ON cl_sales_planning_month.cl_products_id_c = cl_products.id LEFT JOIN cl_brands ON   ";
query += "   cl_products.cl_brands_id_c=cl_brands.id LEFT JOIN cl_therapies ON   ";
query += "   cl_products.cl_therapies_id_c=cl_therapies.id WHERE   ";
 query += "            cl_sales_planning_month.month_name_c = MONTHNAME(CURRENT_DATE - INTERVAL 2 MONTH) AND  ";
      query += "            cl_sales_planning_month.year_c = YEAR(CURRENT_DATE - INTERVAL 2 MONTH)  AND";

query += "   cl_sales_planning_month.user_id_c IN ("+ params["childs"].value +") ";
query += "   GROUP BY therapy,monthyear   ";
query += "   ORDER BY STR_TO_DATE(cl_sales_planning_month.year_c,'%Y') ASC,   ";
query += "  STR_TO_DATE(cl_sales_planning_month.month_name_c,'%M') ASC, Actual_plan DESC   "; 

このために、私はJavaプログラムを書きました:

package com.waprau;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.regex.Pattern;

public class SeparateTableNamesColumnNames {
    public static void main(String[] args) {
        File file = new File("/home/waprau/Desktop/query");
        //Pattern = new Pattern("([^\\s]+(\\.(?i))$)");

        try {
            Scanner scanner = new Scanner(file);
            scanner.useDelimiter("\\s|=|,|\\)|\\(|this.|\\].");

            while(scanner.hasNext()){
                if(scanner.next().matches("(?<!\\.)\\b[a-zA-Z]\\w*\\.[a-zA-Z]\\w*\\b(?!\\.)"))
                 System.out.println(scanner.next());;
               }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
}

上記のプログラムを使用すると、すべての単語を分離できます。しかし、accounts.name、cl_sales_planning_month.year_c、cl_products.volume、cl_brands.name、cl_therapies.nameなど、単一のドットまたはピリオドを含む単語のみを取得したいのですが、パターンやできるものを見つけることができませんこれらの単語をファイルから分離します。

しかし、それは機能していません。

これは私が得ている結果です:

ここに画像の説明を入力

そして、これは私が欲しいものです:

ここに画像の説明を入力

どんな助けでも大歓迎です。

4

3 に答える 3

1

ドットを含む単語を照合するには、次を使用できます"\\w+\\.\\w+"

\w文字、数字、およびアンダースコアに一致します。

ただし、それは複数の期間があったものとも一致します。ルックアラウンドを使用して、一致する単語の前後に別のピリオドがないことを確認することで、これを改善できます。

"(?<!\\.)\\b\\w+\\.\\w+\\b(?!\\.)"

これはドットを含む単語と一致し、直前または直後にドットを含めることはできません。\b単語の境界です。

ただし、これは。のような10進数と一致します123.45。テーブルには数字を含めることができますが、数字で始めることはできません。したがって、各単語が文字で始まることを確認することもできます。

"(?<!\\.)\\b[a-zA-Z]\\w*\\.[a-zA-Z]\\w*\\b(?!\\.)"
于 2013-03-04T14:28:54.200 に答える
1

ピリオド.は「任意の文字」を意味するため、エスケープする必要があります。これは通常の文字列エスケープ ( など\n) ではないため、2 つのバックスラッシュを使用します。\\.

また\\s

于 2013-03-04T14:42:47.513 に答える
1

正規表現に関係なく(dan1111の回答がそれをカバーしているようです)。Java コードに欠陥があり、scanner.next() が次の文字列を取得します。2 回呼び出しているため、一致したものが出力されません。代わりに、一致するたびにアイテムを印刷します。

次のようにループを変更すると、必要なものが出力されるようです。

String tmp;
while (scanner.hasNext()) {
    // Store next item so we can match AND print it.
    tmp = scanner.next();
    if (tmp.matches("(?<!\\.)\\b[a-zA-Z]\\w*\\.[a-zA-Z]\\w*\\b(?!\\.)"))
        System.out.println(tmp);
}
于 2013-03-04T16:07:44.523 に答える