[php] PHP : 괄호 안의 텍스트를 추출하는 가장 좋은 방법은 무엇입니까?
괄호 사이에 텍스트 세트를 추출하는 가장 좋은 / 가장 효율적인 방법은 무엇입니까? 가능한 가장 효율적인 방법으로 “이 (텍스트)를 제외한 모든 것을 무시”문자열에서 “텍스트”문자열을 얻고 싶다고 가정 해보십시오.
지금까지 내가 생각 해낸 최고는 다음과 같습니다.
$fullString = "ignore everything except this (text)";
$start = strpos('(', $fullString);
$end = strlen($fullString) - strpos(')', $fullString);
$shortString = substr($fullString, $start, $end);
이 작업을 수행하는 더 좋은 방법이 있습니까? 일반적으로 정규식을 사용하는 것이 효율성이 떨어지는 경향이 있다는 것을 알고 있지만 함수 호출 수를 줄일 수 없다면 이것이 가장 좋은 방법일까요? 생각?
답변
나는 정규식을하고 그것을 극복 할 것입니다. 엄청난 성능 문제가 될만큼 충분한 반복 작업을 수행하지 않는 한 코딩이 더 쉽습니다 (그리고 되돌아 보면 이해할 수 있음).
$text = 'ignore everything except this (text)';
preg_match('#\((.*?)\)#', $text, $match);
print $match[1];
답변
따라서 실제로 게시 한 코드는 작동하지 않습니다. substr()'s
매개 변수는 $ string, $ start 및 $ length 이고 strpos()'s
매개 변수는 $haystack
, $needle
입니다. 약간 수정 :
$ str = "이 (텍스트)를 제외한 모든 것을 무시합니다"; $ start = strpos ($ str, '('); $ end = strpos ($ str, ')', $ start + 1); $ length = $ end-$ start; $ result = substr ($ str, $ start + 1, $ length-1);
몇 가지 미묘함 : 두 번째 괄호 $start + 1
에서 strpos()
검색 을 수행하는 동안 PHP를 돕기 위해 offset 매개 변수에 사용 했습니다 . 우리는 증가 $start
하나를 줄일 $length
경기에서 괄호를 제외 할 수 있습니다.
또한,이 코드에는 오류 검사 가 없습니다 . 를 수행하기 전에 확인 $start
하고 $end
=== false가 아닌지 확인 하고 싶을 것 substr
입니다.
strpos/substr
정규식 대 사용에 관해서는 ; 성능면에서이 코드는 정규식을 능가합니다. 그래도 조금 더 말이 있습니다. 나는 먹고 숨을 쉬기 strpos/substr
때문에 너무 신경 쓰지 않지만 다른 누군가는 정규식의 간결함을 선호 할 수 있습니다.
답변
정규식을 사용하십시오.
if( preg_match( '!\(([^\)]+)\)!', $text, $match ) )
$text = $match[1];
답변
이것은 ‘[‘와 ‘]’사이의 모든 텍스트를 추출하여 2 개의 개별 배열 (즉, 한 배열의 괄호 안의 텍스트와 다른 배열의 괄호 밖의 텍스트)을 저장하는 샘플 코드입니다.
function extract_text($string)
{
$text_outside=array();
$text_inside=array();
$t="";
for($i=0;$i<strlen($string);$i++)
{
if($string[$i]=='[')
{
$text_outside[]=$t;
$t="";
$t1="";
$i++;
while($string[$i]!=']')
{
$t1.=$string[$i];
$i++;
}
$text_inside[] = $t1;
}
else {
if($string[$i]!=']')
$t.=$string[$i];
else {
continue;
}
}
}
if($t!="")
$text_outside[]=$t;
var_dump($text_outside);
echo "\n\n";
var_dump($text_inside);
}
출력 : extract_text ( “hello how are you?”); 다음을 생성합니다.
array(1) {
[0]=>
string(18) "hello how are you?"
}
array(0) {
}
extract_text ( “안녕하세요 [http://www.google.com/test.mp3] 잘 지내세요?”); 생산할 것이다
array(2) {
[0]=>
string(6) "hello "
[1]=>
string(13) " how are you?"
}
array(1) {
[0]=>
string(30) "http://www.google.com/test.mp3"
}
답변
이 기능이 유용 할 수 있습니다.
public static function getStringBetween($str,$from,$to, $withFromAndTo = false)
{
$sub = substr($str, strpos($str,$from)+strlen($from),strlen($str));
if ($withFromAndTo)
return $from . substr($sub,0, strrpos($sub,$to)) . $to;
else
return substr($sub,0, strrpos($sub,$to));
}
$inputString = "ignore everything except this (text)";
$outputString = getStringBetween($inputString, '(', ')'));
echo $outputString;
//output will be test
$outputString = getStringBetween($inputString, '(', ')', true));
echo $outputString;
//output will be (test)
strpos () => 문자열에서 첫 번째 발생 위치를 찾는 데 사용됩니다.
strrpos () => 문자열에서 첫 번째 발생 위치를 찾는 데 사용됩니다.
답변
이미 게시 된 정규식 솔루션- \((.*?)\)
및 \(([^\)]+)\)
– 열기 및 닫기 괄호 사이 의 가장 안쪽 문자열을 반환하지 않습니다 . 문자열이 Text (abc(xyz 123)
있으면 둘 다 a가 아니라 전체 일치로 반환(abc(xyz 123)
됩니다 (xyz 123)
.
일치 에 괄호가 포함되어야하는 경우, 괄호 안에 다른 열기 및 닫기 괄호가없는 하위 문자열 ( preg_match
첫 번째 preg_match_all
항목을 가져오고 모든 항목을 가져 오려면 with 사용)과 일치하는 패턴 은 다음과 같습니다.
\([^()]*\)
또는 괄호없이 값을 얻고 자합니다.
\(([^()]*)\) // get Group 1 values after a successful call to preg_match_all, see code below
\(\K[^()]*(?=\)) // this and the one below get the values without parentheses as whole matches
(?<=\()[^()]*(?=\)) // less efficient, not recommended
교체 *
와 +
문자 1 이상 사이에 존재해야하는 경우 (
와 )
.
세부 사항 :
\(
-여는 둥근 괄호 (문자 클래스 외부에서 사용되므로 리터럴 괄호를 표시하려면 이스케이프해야 함)[^()]*
– 0 개 이상의 이외의 자(
와)
(이주의(
와)
그 안에 같은 문자 클래스 내에서 이스케이프 할 필요가 없습니다,(
및)
그룹화 및 문자 괄호로 처리됩니다 지정하는 데 사용할 수 없습니다)\)
-닫는 둥근 괄호 (문자 클래스 외부에서 사용되므로 리터럴 괄호를 나타 내기 위해 이스케이프되어야 함).
\(\K
대체 정규식 의 부분 (
이 일치 값에서 일치 하고 생략됩니다 ( \K
일치 재설정 연산자 사용). (?<=\()
는 (
현재 위치의 바로 왼쪽에가 나타나야 하는 긍정적 인 (
룩 비하인드이지만 룩 비하인드 (찾아보기) 패턴이 소비되지 않기 때문에 일치 값에 추가되지 않습니다. 현재 위치의 오른쪽에 문자가 즉시 나타나야 (?=\()
하는 긍정적 인 미리보기입니다 )
.
PHP 코드 :
$fullString = 'ignore everything except this (text) and (that (text here))';
if (preg_match_all('~\(([^()]*)\)~', $fullString, $matches)) {
print_r($matches[0]); // Get whole match values
print_r($matches[1]); // Get Group 1 values
}
산출:
Array ( [0] => (text) [1] => (text here) )
Array ( [0] => text [1] => text here )
답변
function getStringsBetween($str, $start='[', $end=']', $with_from_to=true){
$arr = [];
$last_pos = 0;
$last_pos = strpos($str, $start, $last_pos);
while ($last_pos !== false) {
$t = strpos($str, $end, $last_pos);
$arr[] = ($with_from_to ? $start : '').substr($str, $last_pos + 1, $t - $last_pos - 1).($with_from_to ? $end : '');
$last_pos = strpos($str, $start, $last_pos+1);
}
return $arr; }
이것은 모든 패턴을 배열 형식으로 반환하는 이전 답변에 대한 약간의 개선입니다.
getStringsBetween ( ‘[T] his [] is [test] string [pattern]’)은 다음을 반환합니다.