Regex를 사용하여 문자열을 일치시키는 대신 문자열 생성

StackOverflow https://stackoverflow.com/questions/22115

  •  09-06-2019
  •  | 
  •  

문제

성능 테스트를 위해 많은 양의 데이터를 생성하는 데 도움이 되는 Java 유틸리티를 작성 중입니다.그럴 것이다 정말 내 생성기가 이와 일치하는 항목을 뱉어낼 수 있도록 문자열에 대한 정규식을 지정할 수 있다는 것은 멋진 일입니다.이 작업을 수행하는 데 사용할 수 있는 이미 구운 것이 있습니까?아니면 나를 그곳으로 가장 많이 데려다 주는 도서관이 있습니까?

감사해요

도움이 되었습니까?

해결책

편집하다:

의견에서 언급했듯이 Google Code에는 이를 달성하기 위해 사용할 수 있는 라이브러리가 있습니다.http://code.google.com/p/xeger

또한보십시오 https://github.com/mifmif/Generex 에서 제안한대로 미프미프

원본 메시지:

첫째, 충분히 복잡한 정규식을 사용하면 이것이 불가능할 수 있다고 생각합니다.하지만 간단한 정규 표현식을 위해 무언가를 조합할 수 있어야 합니다.

java.util.regex.Pattern 클래스의 소스 코드를 살펴보면 Node 인스턴스의 내부 표현을 사용한다는 것을 알 수 있습니다.다양한 패턴 구성 요소 각각에는 Node 하위 클래스의 자체 구현이 있습니다.이러한 노드는 트리로 구성됩니다.

이 트리를 순회하는 방문자를 생성함으로써 오버로드된 생성기 메소드 또는 무언가를 함께 연결하는 일종의 빌더를 호출할 수 있어야 합니다.

다른 팁

Xeger(자바) 뿐만 아니라 그것을 할 수 있습니다 :

String regex = "[ab]{4,6}c";
Xeger generator = new Xeger(regex);
String result = generator.generate();
assert result.matches(regex);

원래 포스터를 돕기에는 너무 늦었지만 새로 온 사람에게는 도움이 될 수 있습니다. 제네렉스 정규식을 사용하여 문자열을 생성하는 데 필요한 많은 기능(무작위 생성, 인덱스를 기반으로 문자열 생성, 모든 문자열 생성 등)을 제공하는 유용한 Java 라이브러리입니다.

예 :

Generex generex = new Generex("[0-3]([a-c]|[e-g]{1,2})");

// generate the second String in lexicographical order that matches the given Regex.
String secondString = generex.getMatchedString(2);
System.out.println(secondString);// it print '0b'

// Generate all String that matches the given Regex.
List<String> matchedStrs = generex.getAllMatchedStrings();

// Using Generex iterator
Iterator iterator = generex.iterator();
while (iterator.hasNext()) {
    System.out.print(iterator.next() + " ");
}
// it prints 0a 0b 0c 0e 0ee 0e 0e 0f 0fe 0f 0f 0g 0ge 0g 0g 1a 1b 1c 1e
// 1ee 1e 1e 1f 1fe 1f 1f 1g 1ge 1g 1g 2a 2b 2c 2e 2ee 2e 2e 2f 2fe 2f 2f 2g
// 2ge 2g 2g 3a 3b 3c 3e 3ee 3e 3e 3f 3fe 3f 3f 3g 3ge 3g 3g 1ee

// Generate random String
String randomStr = generex.random();
System.out.println(randomStr);// a random value from the previous String list

나는 내 롤링의 뿌리를 갔다 소유하다 이를 위한 라이브러리(C#에서는 Java 개발자가 이해하기 쉬워야 함).

Rxrdg는 실제 프로젝트를 위한 테스트 데이터 생성 문제에 대한 솔루션으로 시작되었습니다.기본 아이디어는 기존(정규식) 유효성 검사 패턴을 활용하여 이러한 패턴을 따르는 임의의 데이터를 생성하는 것입니다.이렇게 하면 유효한 무작위 데이터가 생성됩니다.

간단한 정규식 패턴에 대한 파서를 작성하는 것은 그리 어렵지 않습니다.문자열을 생성하기 위해 추상 구문 트리를 사용하는 것이 훨씬 더 쉬울 것입니다.

stackoverflow 팟캐스트 11에서:

스폴스키:네.새로운 제품도 있습니다. Team System을 사용하고 싶지 않다면 Redgate의 친구들이 SQL Data Generator라는 제품을 가지고 있습니다.http://www.red-gate.com/products/sql_data_generator/index.htm].가격은 295달러이며, 현실적인 테스트 데이터를 생성합니다.그리고 실제로 존재하는 도시 열에 실제 도시를 생성한 다음 이를 생성할 때 주를 잘못 지정하거나 주를 독일 도시에 넣는 등의 대신에 주를 올바르게 지정하는 등의 작업을 수행합니다.아시다시피 꽤 사실적으로 보이는 데이터를 생성합니다.모든 기능이 무엇인지 잘 모르겠습니다.

이것은 아마도 당신이 찾고 있는 것이 아닐 수도 있지만, 스스로 만드는 것보다 좋은 시작점이 될 수 있습니다.

Google에서 아무것도 찾을 수 없는 것 같으므로 주어진 정규식을 가장 작은 작업 단위(\w, [x-x], \d 등)로 구문 분석하고 지원하기 위한 몇 가지 기본 방법을 작성하여 문제를 해결하는 것이 좋습니다. 그 정규식 문구.

따라서 \w의 경우 임의의 문자를 반환하는 getRandomLetter() 메서드가 있고 두 값 사이에 임의의 문자를 제공하는 getRandomLetter(char startLetter, char endLetter)도 있습니다.

이미 승인된 답변이 있다는 것을 알고 있지만 RedGate의 데이터 생성기 (Craig의 답변에 언급된 것) 그리고 그것은 내가 던진 모든 것에 대해 정말 잘 작동합니다.속도가 빠르고 이로 인해 동일한 정규식을 사용하여 이것이 뱉어내는 등록 코드와 같은 항목에 대한 실제 데이터를 생성하고 싶습니다.

다음과 같은 정규식이 필요합니다.

[A-Z0-9]{3,3}-[A-Z0-9]{3,3}

다음과 같은 수많은 고유 코드를 생성합니다.

LLK-32U

이것은 RedGate가 알아낸 엄청난 비밀 알고리즘인가요? 우리 모두는 운이 좋지 않습니다. 아니면 단순한 필멸의 인간이 실제로 할 수 있는 일인가요?

비행기를 타고 가는데 방금 다음 질문을 봤습니다.나는 가장 쉽지만 비효율적이고 불완전한 솔루션을 작성했습니다.자신만의 파서를 작성하는 데 도움이 되기를 바랍니다.

public static void main(String[] args) {

    String line = "[A-Z0-9]{16}";
    String[] tokens = line.split(line);
    char[] pattern = new char[100];
    int i = 0;
    int len = tokens.length;
    String sep1 = "[{";
    StringTokenizer st = new StringTokenizer(line, sep1);

    while (st.hasMoreTokens()) {
        String token = st.nextToken();
        System.out.println(token);

        if (token.contains("]")) {
            char[] endStr = null;

            if (!token.endsWith("]")) {
                String[] subTokens = token.split("]");
                token = subTokens[0];

                if (!subTokens[1].equalsIgnoreCase("*")) {
                    endStr = subTokens[1].toCharArray();
                }
            }

            if (token.startsWith("^")) {
                String subStr = token.substring(1, token.length() - 1);
                char[] subChar = subStr.toCharArray();
                Set set = new HashSet<Character>();

                for (int p = 0; p < subChar.length; p++) {
                    set.add(subChar[p]);
                }

                int asci = 1;

                while (true) {
                    char newChar = (char) (subChar[0] + (asci++));

                    if (!set.contains(newChar)) {
                        pattern[i++] = newChar;
                        break;
                    }
                }
                if (endStr != null) {
                    for (int r = 0; r < endStr.length; r++) {
                        pattern[i++] = endStr[r];
                    }
                }

            } else {
                pattern[i++] = token.charAt(0);
            }
        } else if (token.contains("}")) {
            char[] endStr = null;

            if (!token.endsWith("}")) {
                String[] subTokens = token.split("}");
                token = subTokens[0];

                if (!subTokens[1].equalsIgnoreCase("*")) {
                    endStr = subTokens[1].toCharArray();
                }
            }

            int length = Integer.parseInt((new StringTokenizer(token, (",}"))).nextToken());
            char element = pattern[i - 1];

            for (int j = 0; j < length - 1; j++) {
                pattern[i++] = element;
            }

            if (endStr != null) {
                for (int r = 0; r < endStr.length; r++) {
                    pattern[i++] = endStr[r];
                }
            }
        } else {
            char[] temp = token.toCharArray();

            for (int q = 0; q < temp.length; q++) {
                pattern[i++] = temp[q];
            }
        }
    }

    String result = "";

    for (int j = 0; j < i; j++) {
        result += pattern[j];
    }

    System.out.print(result);
}

String::Random(Perl)의 저자처럼 자신만의 파서를 작성해야 합니다.사실, 그는 해당 모듈의 어느 곳에서도 정규식을 사용하지 않고 단지 Perl-coders에 익숙한 방식입니다.

반면에 다음을 살펴볼 수도 있습니다. 출처, 몇 가지 지침을 얻으려면.


편집하다:젠장, 블레어 총리가 나한테 15초 차이로 펀치를 날렸어.

완전한 PCRE 정규식을 지원하는 것과는 거리가 멀지만, 정규식과 유사한 문자열을 가져와 변형을 생성하기 위해 다음 Ruby 메서드를 작성했습니다.(언어 기반 CAPTCHA의 경우)

# q = "(How (much|many)|What) is (the (value|result) of)? :num1 :op :num2?"
# values = { :num1=>42, :op=>"plus", :num2=>17 }
# 4.times{ puts q.variation( values ) }
# => What is 42 plus 17?
# => How many is the result of 42 plus 17?
# => What is the result of 42 plus 17?
# => How much is the value of 42 plus 17?
class String
  def variation( values={} )
    out = self.dup
    while out.gsub!( /\(([^())?]+)\)(\?)?/ ){
      ( $2 && ( rand > 0.5 ) ) ? '' : $1.split( '|' ).random
    }; end
    out.gsub!( /:(#{values.keys.join('|')})\b/ ){ values[$1.intern] }
    out.gsub!( /\s{2,}/, ' ' )
    out
  end
end

class Array
  def random
    self[ rand( self.length ) ]
  end
end

이 질문은 매우 오래되었지만 제가 직접 검색하다가 우연히 발견한 질문이므로 다른 언어에서도 동일한 기능을 검색할 수 있는 사람들을 위해 몇 가지 링크를 포함하겠습니다.

"중요한" 문자열을 생성하려면 다음을 고려할 수 있습니다.

백로 http://elarson.pythonanywhere.com/정규 표현식을 덮는 "사악한" 문자열을 생성합니다.

뮤트렉스 http://cs.unibg.it/mutrex/정규식 돌연변이를 통해 오류 감지 문자열을 생성합니다.

둘 다 학문적 도구이며(저는 후자의 저자 중 한 명입니다) 합리적으로 잘 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top