14

Java を使用して、単一の数値または範囲を表す、ユーザーが入力した文字列を解析しています。ユーザーは次の文字列を入力できます。

10-19

10-19そして彼の意図は-->からの整数を使うことです10,11,12...19

ユーザーは、番号のリストを指定することもできます。

10,15,19

または上記の組み合わせ:

10-19,25,33

おそらく正規表現に基づいて、この解析を実行するための便利な方法はありますか? または、 を使用して文字列を分割しString.split()、特殊記号 (この場合は「,」と「-」) を手動で繰り返す必要がありますか?

4

4 に答える 4

15

これは私がそれについて行く方法です:

  1. ,を区切り文字として使用して分割します。
  2. この正規表現に一致する場合: ^(\\d+)-(\\d+)$、範囲があることがわかります。次に、数値を抽出して範囲を作成します (わからないので、最初の桁が 2 番目の桁よりも小さいことを確認することをお勧めします...)。その後、それに応じて行動します。
  3. この正規表現に一致する場合:^\\d+$番号が 1 つしかないことがわかります。したがって、特定のページがあります。その後、私はそれに応じて行動します。
于 2012-10-22T12:45:35.763 に答える
11

このテスト済み (および完全にコメント済み) の正規表現ソリューションは、OP 要件を満たしています。

Java 正規表現ソリューション

// TEST.java 20121024_0700
import java.util.regex.*;
public class TEST {
    public static Boolean isValidIntRangeInput(String text) {
        Pattern re_valid = Pattern.compile(
            "# Validate comma separated integers/integer ranges.\n" +
            "^             # Anchor to start of string.         \n" +
            "[0-9]+        # Integer of 1st value (required).   \n" +
            "(?:           # Range for 1st value (optional).    \n" +
            "  -           # Dash separates range integer.      \n" +
            "  [0-9]+      # Range integer of 1st value.        \n" +
            ")?            # Range for 1st value (optional).    \n" +
            "(?:           # Zero or more additional values.    \n" +
            "  ,           # Comma separates additional values. \n" +
            "  [0-9]+      # Integer of extra value (required). \n" +
            "  (?:         # Range for extra value (optional).  \n" +
            "    -         # Dash separates range integer.      \n" +
            "    [0-9]+    # Range integer of extra value.      \n" +
            "  )?          # Range for extra value (optional).  \n" +
            ")*            # Zero or more additional values.    \n" +
            "$             # Anchor to end of string.           ", 
            Pattern.COMMENTS);
        Matcher m = re_valid.matcher(text);
        if (m.matches())    return true;
        else                return false;
    }
    public static void printIntRanges(String text) {
        Pattern re_next_val = Pattern.compile(
            "# extract next integers/integer range value.    \n" +
            "([0-9]+)      # $1: 1st integer (Base).         \n" +
            "(?:           # Range for value (optional).     \n" +
            "  -           # Dash separates range integer.   \n" +
            "  ([0-9]+)    # $2: 2nd integer (Range)         \n" +
            ")?            # Range for value (optional). \n" +
            "(?:,|$)       # End on comma or string end.", 
            Pattern.COMMENTS);
        Matcher m = re_next_val.matcher(text);
        String msg;
        int i = 0;
        while (m.find()) {
            msg = "  value["+ ++i +"] ibase="+ m.group(1);
            if (m.group(2) != null) {
                msg += " range="+ m.group(2);
            };
            System.out.println(msg);
        }
    }
    public static void main(String[] args) {
        String[] arr = new String[] 
                { // Valid inputs:
                    "1", 
                    "1,2,3",
                    "1-9",
                    "1-9,10-19,20-199",
                    "1-8,9,10-18,19,20-199",
                  // Invalid inputs:
                    "A", 
                    "1,2,",
                    "1 - 9",
                    " ",
                    ""
                };
        // Loop through all test input strings:
        int i = 0;
        for (String s : arr) {
            String msg = "String["+ ++i +"] = \""+ s +"\" is ";
            if (isValidIntRangeInput(s)) {
                // Valid input line
                System.out.println(msg +"valid input. Parsing...");
                printIntRanges(s);
            } else {
                // Match attempt failed
                System.out.println(msg +"NOT valid input.");
            } 
        }
    }
}

出力:

r'''
String[1] = "1" is valid input. Parsing...
  value[1] ibase=1
String[2] = "1,2,3" is valid input. Parsing...
  value[1] ibase=1
  value[2] ibase=2
  value[3] ibase=3
String[3] = "1-9" is valid input. Parsing...
  value[1] ibase=1 range=9
String[4] = "1-9,10-19,20-199" is valid input. Parsing...
  value[1] ibase=1 range=9
  value[2] ibase=10 range=19
  value[3] ibase=20 range=199
String[5] = "1-8,9,10-18,19,20-199" is valid input. Parsing...
  value[1] ibase=1 range=8
  value[2] ibase=9
  value[3] ibase=10 range=18
  value[4] ibase=19
  value[5] ibase=20 range=199
String[6] = "A" is NOT valid input.
String[7] = "1,2," is NOT valid input.
String[8] = "1 - 9" is NOT valid input.
String[9] = " " is NOT valid input.
String[10] = "" is NOT valid input.
'''

このソリューションは、入力行を検証する方法と、各行から値コンポーネントを解析/抽出する方法を単に示していることに注意してください。範囲値の場合、2 番目の整数が最初の整数よりも大きいことをさらに検証しません。ただし、このロジック チェックは簡単に追加できます。

Edit:2012-10-24 07:00インデックス i をゼロからカウントするように修正しました。

于 2012-10-23T03:18:30.967 に答える
1

使用できます

strinput = '10-19,25,33'
eval(cat(2,'[',strrep(strinput,'-',':'),']'))

いくつかの入力チェックを含めるのが最善です。また、負の数はこの方法で問題を引き起こします。

于 2012-10-22T12:46:47.783 に答える
-4

eval最も簡単なアプローチでは、これに悪を使用できます

A = eval('[10:19,25,33]')

A =

   10    11    12    13    14    15    16    17    18    19    25    33

しかしもちろん、そうする前によく考えるべきです。これがユーザー指定の文字列である場合は特に! ユーザーが他のコマンドを提供した場合に何が起こるか想像してみてください...

eval('!rm -rf /')

本当に欲しいもの以外に何もないことを確認する必要があります。でこれを行うことができますregexp

于 2012-10-22T12:45:46.437 に答える