2012-01-18 5 views
3

나는이 것을 이해할 수 없다는 이유로 매우 어리 석다.하지만 나는 그 사실을 파악할 수 없다. 정규식 문자열을 패턴으로 대체해야하지만, 두 가지 예제를 통해 찾았지만 정직하게도 그 어느 때보 다 혼란 스러웠습니다.정규식 패턴을 정규식 패턴으로 대체하는 방법은 무엇입니까?

이 내 현재 시도 :

$string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <61399130249>","SIP/1037-00000014","SIP/CL-00000015","Dial","SIP/CL/61436523277,45","2011-08-26 14:47:06","2011-08-26 14:47:15","2011-08-26 '; 
$pattern = '["SIP/CL/\d*?,\d*?",]'; 
$replacement = '"SIP/CL/\1|\2",'; 
$string = preg_replace($pattern, $replacement, $string); 
print($string); 

하지만 그건 그냥 공백으로 \1\2을 대체합니다. 그래서 분명히 나는 ​​전체 개념을 얻지 못하고있다.

는 내가 말하고자하고있어 변경하는 것입니다 :

잘못 포맷 된 CSV에서 쉼표 내 다른 스크립트의 일부를 슬로우
this: "SIP/CL/61436523277,45" 
to: "SIP/CL/61436523277|45" 

.

+1

그것이 따옴표 사이에 같이 ... 당신은 사용합니까, 제대로 포맷하지 않는 것 ['fgetcsv'] (http://www.php.net/fgetcsv) 이거 당신 아닌가요? 또는 문자열 인 경우 ['str_getcsv'] (http://www.php.net/str_getcsv). – Wrikken

+0

나는 아니었지만 나는 지금이다. 어쨌든이 정규식 대체 양식을 배울 필요했습니다. 한 돌로 두 마리의 새가 죽었다. :). 나는 fgetcsv에 대해 알고 있었지만, 내 목적에 부합하지 않았다. (1.8GB + csv ...., mem에 모든 것을로드 할 수 없다.)하지만 str_getcsv는 잘 작동했다. :) – Mattisdada

+0

나중에 참조 용으로 :'fgetcsv'는 전체 파일을 메모리로 읽어 들이지 않고 줄 단위로 읽습니다;) – Wrikken

답변

2

당신은 괄호를 놓치고, 패턴은 다음과 같아야합니다

$pattern = '["SIP/CL/(\d*),(\d*)",]'; 
+0

그게 뭡니까? 나는 그런 멍청한 기분이 든다. '고마워요 :) 완벽하게 작동했습니다. – Mattisdada

+0

브래킷 외부를 사용하여 비 gready 연산자의 의미를 변경했습니다. – meouw

+0

@ user1130968 가장 유용한 답변을 대답으로 표시하는 것은 감사합니다.) (그렇다면 FAQ가 있습니다.) – Vyktor

2

을 나는 당신이 필요가 있다고 생각 : - () -

$pattern = '["SIP/CL/(\d+),(\d+)",]'; 

괄호를, 내부의 일치를 캡처 당신을 허용 대체 패턴으로 참조하십시오.

또한 일치 패턴으로 캡처를 확장하여 교체 패턴을 단순화 할 수있다 : 당신의 $replacement\1\2$pattern캡처 그룹를 참조하기위한 것입니다

$pattern = '[("SIP/CL/\d+),(\d+",)]'; 
$replacement = '\1|\2'; 
2

역 참조. 캡처 된 그룹은 괄호 (())를 사용하여 저장됩니다.

봅니다 (나는 당신의 정규식 구분 기호 변경 [] 아래 주석의 응답을 대기 !에) :

$pattern = '!"SIP/CL/(\d*?),(\d*?)",!'; 
$replacement = '"SIP/CL/\1|\2",'; 

은 또한 당신이 당신의 $pattern에 콤마가 이후 $string"SIP/CL/61436523277,45"에 그 것이다 끝난 경우주의를 개종하지 마십시오. 그 후행 쉼표를 제거하는 것이 좋습니다.

또한 현재 정규식은 "SIP/CL/,""SIP/CL/|"으로 변환합니다. 귀하의 의도가 아닌 경우 \d (예 : 0 개 이상의 일치)을 + (일치하는 항목 1 개 이상)으로 변경 한 후 *을 변경하십시오.

+0

이 경우에는 문자 클래스가 아니라 [와]가 구분 기호로 사용됩니다. – meouw

+0

은 SIP/CL/{numbers 여기}가되도록 패턴을 지정하지 않으므로 SIP/CL/(\ d *?), (\ d *?) ","그렇지 않으면 첫 번째 참조가 재미 있습니다. 당신의 대체품이'SIP/CL/SIP/CL/numbershere | numbersagain' – Michael

+0

@ meouw 인 것처럼, 나는 그것을 잊고 환호했다. 하지만 [[''''''''''''''''''''''''''''''''''''''''와''''''' –

0

은 내가 그랬어이

$string = '26 14:46:54",,"2011-08-26 14:47:02",8,0,"BUSY","DOCUMENTATION","1314370014.18","","","61399130249","7466455647","from-internal","""Oh Snap"" <61399130249>","SIP/1037-00000014","SIP/CL-00000015","Dial","SIP/CL/61436523277,45","2011-08-26 14:47:06","2011-08-26 14:47:15","2011-08-26 '; 
$pattern = '/SIP\/CL\/([0-9]+),([0-9]+)/'; 
$replacement = 'SIP/CL/\1|\2'; 
$string = preg_replace($pattern, $replacement, $string); 
print($string); 
관련 문제