문제

여기에 문제가에 달렸다.저는 속성 문의 양식

"x=1 and y=abc and z=c4g and ..."

몇 가지 특성이 있는 숫자 값,일부는 알파 값은 일부가 혼합된,일부입니다.

모든 문자열 하"x=someval and y=anotherval"처음에는,그러나 몇 가지 하지 않습니다.저는 세 가지를 내가해야 할 수 있습니다.

  1. 유효성을 검증할 문자열을 특정들 xy.
  2. 실제로 구문 분석에 대한 값 xy.
  3. 나머지의 문자열입니다.

주어진 예 맨 위에,이것은 다음과 같은 변수:

$x = 1;
$y = "abc";
$remainder = "z=c4g and ..."

나의 질문은:이 있(합리적으로)간단한 방법으로 이러한 구문 분석 검증으로 하나의 정규 표현식?즉:

if ($str =~ /someexpression/)
{
    $x = $1;
    $y = $2;
    $remainder = $3;
}

참고하는 문자열 수 있습으로 구성 xy 특성이 있습니다.이것은 유효한 문자열입니다.

나는 나의 솔루션에 대한 답변으로,그러나 그것을 만나지 않 내 single-regex 니다.

도움이 되었습니까?

해결책

나는 최고의에서는 정기적인 표현,하지만 이것은 아주 가까이 무엇을 찾고 있:

/x=(.+) and y=([^ ]+)( and (.*))?/

를 제외하고 사용할$1,$2$4.에서 사용:

my @strs = ("x=1 and y=abc and z=c4g and w=v4l",
            "x=yes and y=no",
            "z=nox and w=noy");

foreach (@strs) {
    if ($_ =~ /x=(.+) and y=([^ ]+)( and (.*))?/) {
        $x = $1;
        $y = $2;
        $remainder = $4;
        print "x: $x; y: $y; remainder: $remainder\n";
    } else {
        print "Failed.\n";
    }
}

출력:

x: 1; y: abc; remainder: z=c4g and w=v4l
x: yes; y: no; remainder: 
Failed.

이 과정의 목적으로 충분의 오류를 검사하며,검사를 하나라도 통과하지 알아에 대한 모든 것을 입력하지만,이 작동하는 것 같다.

다른 팁

고 가정하고 당신은 또한 당신을 위해 무언가 하고 싶은 다른 이름=값 쌍으로 이것은 어떻게 할 지에 대해서 그것은(를 사용하여 Perl 버전 5.10):

use 5.10.0;
use strict;
use warnings;

my %hash;
while(
    $string =~ m{
       (?: ^ | \G )    # start of string or previous match
       \s*

       (?<key>   \w+ ) # word characters
       =
       (?<value> \S+ ) # non spaces

       \s*             # get to the start of the next match
       (?: and )?
    }xgi
){
    $hash{$+{key}} = $+{value};
}

# to make sure that x & y exist
die unless exists $hash{x} and exists $hash{y};

이전 Perls(적어도 Perl5.6);

use strict;
use warnings;

my %hash;
while(
    $string =~ m{
       (?: ^ | \G )   # start of string or previous match
       \s*

       ( \w+ ) = ( \S+ )

       \s*            # get to the start of the next match
       (?: and )?
    }xgi
){
    $hash{$1} = $2;
}

# to make sure that x & y exist
die unless exists $hash{x} and exists $hash{y};

이러한의 혜택을 추가 작업을 계속하고 업무를 수행해야 하는 경우에는 더 많은 데이터입니다.

으로 매우 간단한 수정하 러드의 버전

/^x=(.+) and y=([^ ]+)(?: and (.*))?/

를 사용할 수 있는$1,$2$3(?:게 비캡처 group),그리고 것을 보장하는 문자열로 시작하"x="보다는 허용"not_x="치

는 경우에 당신은 더 나은 지식을 가지고 무엇 x 와 y 값이 될 것입니다,이해하는 데 사용될 조 regex 더:

my @strs = ("x=1 and y=abc and z=c4g and w=v4l",
        "x=yes and y=no",
        "z=nox and w=noy",
        "not-x=nox and y=present",
        "x=yes and w='there is no and y=something arg here'");

foreach (@strs) {
    if ($_ =~ /^x=(.+) and y=([^ ]+)(?: and (.*))?/) {
        $x = $1;
        $y = $2;
        $remainder = $3;
        print "x: {$x}; y: {$y}; remainder: {$remainder}\n";
    } else {
        print "$_ Failed.\n";
    }
}

출력:

x: {1}; y: {abc}; remainder: {z=c4g and w=v4l}
x: {yes}; y: {no}; remainder: {}
z=nox and w=noy Failed.
not-x=nox and y=present Failed.
x: {yes and w='there is no}; y: {something}; remainder: {}

참고 누락된 부분의 마지막 테스트 때문에 현재 버전의 테스트 요구하는 공백이 없는 경우,x 테스트는 동일한 제한이 있는 문자열 것에 실패했습니다.

러드와 Cebjyre 받고 있는 대부분의 방법이 있지만 그들은 모두 특정 문제점:

러드는 제안:

/x=(.+) y=([^]+)(고(.*))?/

Cebjyre 수정한다:

/^x=(.+) y=([^ ]+)(?:고(.*))?/

두번째 버전은 더 나은 것이기 때문에 혼동하지"not_x=foo""x=foo"하지만 받아들이는 것 같은"x="foo"z=바 y=baz"설정 1 달러="foo z=바하는"바람직하지 않습니다.

이것은 아마도 당신이 찾고있는 무엇:

/^x=(\w+)y=(\w+)(?:고(.*))?/

이것을 허용하지 않도 사 x=y=옵션,장소 및할 수 있고 선택 사항"고..."는 것에서$3

여기에 기본적으로 무엇을 했는지 이를 해결하기:

($x_str, $y_str, $remainder) = split(/ and /, $str, 3);

if ($x_str !~ /x=(.*)/)
{
    # error
}

$x = $1;

if ($y_str !~ /y=(.*)/)
{
    # error
}

$y = $1;

나는 생략 몇 가지 추가 유효성 검사 오류를 처리합니다.이 기술은 일이지만,그것은 없으로 간결한 또는 예쁜 나가 좋아했을 것이다.내가 누군가를 희망하는 것입니다 더 나은 제안한다.

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