정규 표현식 / 구문 분석 DIG 출력 / 이중 인용문에서 텍스트 추출
문제
정규 표현을 파악하는 데 도움이 필요합니다. DIG 명령을 실행 중이며 출력을 사용해야합니다. PHP를 사용하여 배열로 배열하고 깔끔하게 배열해야합니다.
다음과 같은 출력을 발굴합니다.
m0.ttw.mydomain.tel. 60 IN TXT ".tkw" "1" "20090624-183342" "Some text here1"
m0.ttw.mydomain.tel. 60 IN TXT ".tkw" "1" "20090624-183341" "Some text here2"
나는 이것을 얻고 싶다 :
Array
(
[0] => Array
(
[0] => .tkw
[1] => 1
[2] => 20090624-183342
[3] => Some text here1
)
[1] => Array
...
)
이중 따옴표 안에 내용이 필요합니다. 나 ~할 수 있다 DIG 출력 라인을 라인별로 구문 분석하지만 모든 것에서 REGEX 패턴을 일치시키는 경우 더 빠를 것이라고 생각합니다 ...
생각?
해결책
이것은 한 줄로 가까워집니다
preg_match_all( '/"([^"]+)"\s*"([^"]+)"\s*"([^"]+)"\s*"([^"]+)"/', $text, $matches, PREG_SET_ORDER );
print_r( $matches );
그러나 preg_match* 기능의 작동 방식에 따라 전체 일치는 각 경기 그룹의 인덱스 0에 포함됩니다. 당신이 정말로 원한다면 이것을 고칠 수 있습니다.
array_walk( $matches, create_function( '&$array', 'array_shift( $array );return $array;' ) );
다른 팁
PHP 정규식에 대해서는 잘 모르겠지만 Perl에서는 간단합니다.
my $c = 0;
print <<EOF;
Array
(
EOF
foreach (<STDIN>) {
if (/[^"]*"([^"]*)"\s+"([^"]*)"\s+"([^"]*)"\s+"([^"]*)"/) {
print <<EOF;
[$c] => Array
(
[0] = $1
[1] = $2
[2] = $3
[3] = $4
)
EOF
$c++;
}
}
print <<EOF;
)
EOF
이것은 몇 가지 제한 사항, 즉 다음과 같습니다.
- 따옴표의 텍스트가 인용문을 피할 수 있다면 작동하지 않습니다 (예 :
\"
) - 인용 된 4 개의 값 만 지원하는 것은 하드 코딩됩니다.
암호:
<?php
$str = 'm0.ttw.mydomain.tel. 60 IN TXT ".tkw" "1" "20090624-183342" "Some text here1"
m0.ttw.mydomain.tel. 60 IN TXT ".tkw" "1" "20090624-183341" "Some text here2"';
header('Content-Type: text/plain');
$matches = array();
preg_match_all('/(".*").*(".*").*(".*").*(".*")/U', $str, $matches, PREG_SET_ORDER);
print_r($matches);
?>
산출:
Array ( [0] => Array ( [0] => ".tkw" "1" "20090624-183342" "Some text here1" [1] => ".tkw" [2] => "1" [3] => "20090624-183342" [4] => "Some text here1" ) [1] => Array ( [0] => ".tkw" "1" "20090624-183341" "Some text here2" [1] => ".tkw" [2] => "1" [3] => "20090624-183341" [4] => "Some text here2" ) )
당신이 요청한 것이 아니라 효과가있는 것은 수많은 인용문을 가진 문자열에 사용될 수 있으며, 평균 정규 표현보다 더 읽기 쉬운 이점 (더 많은 코드를 희생 함).
class GetQuotedText {
const STATE_OUTSIDE = 'STATE_OUTSIDE';
const STATE_INSIDE = 'STATE_INSIDE';
static private $input;
static private $counter;
static private $state;
static private $results;
static private $current;
static private $full;
static private $all;
static private function setInput($string) {
$this->input = $string;
}
static private function init($string) {
self::$current = array();
self::$full = array();
self::$input = $string;
self::$state = self::STATE_OUTSIDE;
}
static public function getStrings($string) {
self::init($string);
for(self::$counter=0;self::$counter<strlen(self::$input);self::$counter++){
self::parse(self::$input[self::$counter]);
}
self::saveLine();
return self::$all;
}
static private function parse($char) {
switch($char){
case '"':
self::encounteredToken($char);
break;
case "\n": //deliberate fall through for "\n" and "\r"
case "\r":
self::encounteredToken($char);
break;
default:
if(self::$state == self::STATE_INSIDE) {
self::action($char);
}
}
}
static private function encounteredToken($token) {
switch($token) {
case '"':
self::swapState();
break;
case "\n": //deliberate fall through for "\n" and "\r"
case "\r":
self::saveArray();
self::saveLine();
break;
}
return;
}
static private function swapState() {
if(self::$state == self::STATE_OUTSIDE) {
self::$state = self::STATE_INSIDE;
}
else {
self::$state = self::STATE_OUTSIDE;
self::saveArray();
}
}
static public function saveLine() {
self::$all[] = self::$full;
self::$full = array();
//reset state when line ends
self::$state = self::STATE_OUTSIDE;
}
static private function saveArray() {
if(count(self::$current) > 0) {
self::$full[] = implode ('',self::$current);
self::$current = array();
}
}
static private function action($char) {
self::$current[] = $char;
}
}
$input = 'm0.ttw.mydomain.tel. 60 IN TXT ".tkw" "1" "20090624-183342" "Some text here1"' . "\n" .
'm0.ttw.mydomain.tel. 60 IN TXT ".tkw" "1" "20090624-183341" "Some text here2"';
$strings = GetQuotedText::getStrings($input);
print_r($strings);
제휴하지 않습니다 StackOverflow