2010-07-18 22 views
9

Ví dụ:Làm cách nào để chỉ trả lại các nhóm được đặt tên với preg_match hoặc preg_match_all?

$string = "This is some text written on 2010-07-18."; 
preg_match('|(?<date>\d\d\d\d-\d\d-\d\d)|i', $string, $arr_result); 
print_r($arr_result); 

Returns:

Array 
(
    [0] => 2010-07-18 
    [date] => 2010-07-18 
    [1] => 2010-07-18 
) 

Nhưng tôi muốn nó được:

Array 
(
    [date] => 2010-07-18 
) 

Trong đối tượng PDO của PHP có một tùy chọn được lọc kết quả từ cơ sở dữ liệu bằng cách loại bỏ các giá trị được đánh số trùng lặp này: PDO::FETCH_ASSOC. Nhưng tôi đã không nhìn thấy sửa đổi tương tự cho các chức năng PCRE trong PHP được nêu ra.

Trả lời

3

Tôi không nghĩ rằng bạn có thể làm cho preg_* làm điều đó, nhưng bạn có thể làm điều đó với một vòng lặp đơn giản. Nhưng tôi không hiểu tại sao những yếu tố đó lại gây ra vấn đề.

+0

Trong các mảng nhỏ, điều này không gây ra vấn đề gì nhưng rất lớn với nhiều mẫu có thể có vấn đề với nhu cầu bộ nhớ cao. Thứ hai, nó trông sạch hơn theo cách đó và sẽ có (với công cụ sửa đổi không tồn tại này) một dòng mã ít hơn, do đó ít khả năng xảy ra lỗi hơn. – rsk82

+0

Hoàn toàn ngược lại: bởi vì điều này không thể được thực hiện bởi PCRE, bạn phải thêm nhiều mã hơn, nơi có thể có nhiều vấn đề hơn. – Charles

+0

Tôi có nghĩa là các phần tử bổ sung trong mảng. – Maerlyn

-1

Hãy thử điều này:

$string = "This is some text written on 2010-07-18."; 
preg_match('|(?<date>\d\d\d\d-\d\d-\d\d)|i',$string,$arr_result); 
echo $arr_result['date']; 
+0

không, đó là sai, tôi có nghĩa là một công cụ sửa đổi để tự động xóa các khóa là số, nó không phải là dễ dàng trên mảng đa chỉnh mà preg_match_all có thể sản xuất – rsk82

9

preg_match không có bất kỳ lá cờ hoặc tùy chọn mà nó chỉ trả lại tên các trận đấu (chưa). Vì vậy, những gì bạn muốn là không trực tiếp có thể. Tuy nhiên bạn có thể xóa tất cả các mục có không phù hợp phím từ mảng các trận đấu của bạn và sau đó bạn sẽ có được những gì bạn đang tìm kiếm:

$matches = array_intersect_key($matches, array_flip(array('name', 'likes'))); 

Demo

3

Nó cũng có thể bỏ đặt tất cả các chỉ số trước khi quay trở lại:

foreach (range(0, floor(count($arr_result)/2)) as $index) { 
    unset($arr_result[$index]); 
} 
1

Tương tự như the answer rằng hakre đăng ở trên, tôi sử dụng đoạn mã này để có được chỉ là các thông số được đặt tên:

$subject = "This is some text written on 2010-07-18."; 
$pattern = '|(?<date>\d\d\d\d-\d\d-\d\d)|i'; 
preg_match_all($pattern, $subject, $matches, PREG_SET_ORDER); 
echo '<pre>Before Diff: ', print_r($matches, 1), '</pre>'; 
$matches = array_diff_key($matches[0], range(0, count($matches[0]))); 
echo '<pre>After Diff: ', print_r($matches, 1), '</pre>'; 

... trong đó sản xuất này:

Before Array 
(
    [0] => Array 
     (
      [0] => 2010-07-18 
      [date] => 2010-07-18 
      [1] => 2010-07-18 
     ) 

) 
After Array 
(
    [date] => 2010-07-18 
) 
+0

Đây là một trong đó làm việc cho tôi. Cảm ơn –

8

Làm thế nào để trở lại chỉ nhóm được đặt tên với preg_match hoặc preg_match_all?

Hiện tại không thể thực hiện (PHP7). Bạn sẽ luôn nhận được một mảng kiểu hỗn hợp, chứa các phím số và có tên.

Cho phép trích dẫn hướng dẫn PHP (http://php.net/manual/en/regexp.reference.subpatterns.php):

subpattern này sau đó sẽ được lập chỉ mục trong mảng các trận đấu bởi vị trí số bình thường của nó và cũng có thể theo tên.


Để giải quyết vấn đề các đoạn mã sau đây có thể giúp:

1. lọc mảng bằng cách sử dụng một kiểm tra is_string trên mảng phím (ví PHP5.6 +)

$array_filtered = array_filter($array, "is_string", ARRAY_FILTER_USE_KEY); 

2.foreach qua các yếu tố và unset nếu chìa khóa mảng is_int() (tất cả các phiên bản PHP)

/** 
* @param array $array 
* @return array 
*/ 
function dropNumericKeys(array $array) 
{ 
    foreach ($array as $key => $value) { 
     if (is_int($key)) { 
      unset($array[$key]); 
     } 
    } 
    return $array; 
} 

của một hàm PHP đơn giản đặt tên dropNumericKeys(). Của nó cho sau xử lý của một mảng phù hợp sau khi chạy preg_match*() sử dụng các nhóm được đặt tên cho phù hợp. Các hàm chấp nhận $array. Nó lặp lại mảng và loại bỏ/bỏ chọn tất cả các khóa với kiểu số nguyên, để lại các khóa với kiểu chuỗi bị ảnh hưởng. Cuối cùng, hàm trả về mảng bằng các khóa có tên "now".

Lưu ý: Chức năng dành cho tính tương thích xuống của PHP. Nó hoạt động trên tất cả các phiên bản. Giải pháp array_filter dựa trên hằng số ARRAY_FILTER_USE_KEY, chỉ khả dụng trên PHP5.6 +. Xem http://php.net/manual/de/array.constants.php#constant.array-filter-use-key

+0

lý do tại sao xác định một hàm nếu bạn có một giải pháp đơn giản như # 1 – Meisner

+2

Hàm này dành cho tính tương thích xuống của PHP. Nó hoạt động trên tất cả các phiên bản. Giải pháp 'array_filter' dựa trên hằng số' ARRAY_FILTER_USE_KEY', chỉ có sẵn trên PHP5.6 +. Xem http://php.net/manual/de/array.constants.php#constant.array-filter-use-key –

0

Tôi đọc trong bài viết của bạn rằng đây là những quá tải có thể bộ nhớ tương lai vv ... Trong trường hợp này, tại sao no't có thể được giải quyết với một unset():

$string = "This is some text written on 2010-07-18."; 
preg_match('|(?<date>\d{4}-\d{2}-\d{2})|i', $string, $arr_result); 
$date = array("date" => $arr_result['date']); 
unset($arr_result, $string);//delete array and string preg_match origen 

print_r($date); 
//or create a new: 
// $arr_result = $date; 
//print_r($arr_result); 
0

tôi sử dụng một số mã giới thiệu và đây là mã cuối cùng hoạt động trên php 5.6+:

$re = '/\d+\r\n(?<start>[\d\0:]+),\d+\s--\>\s(?<end>[\d\0:]+),.*\r\nHOME.*\r\nGPS\((?<x>[\d\.]+),(?<y>[\d\.]+),(?<d>[\d\.]+)\)\sBAROMETER\:(?<h>[\d\.]+)/'; 

$str= file_get_contents($srtFile); 
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0); 
echo '<pre>'; 
$filtered=array_map(function ($d){ 
    return $array_filtered = array_filter($d, "is_string", ARRAY_FILTER_USE_KEY); 
    },$matches); 
var_dump($filtered); 

nếu bạn quan tâm đến những gì nó làm nó đọc dữ liệu vị trí từ một tập tin str rằng DJI bay không người lái tạo ra trong khi quay vi deo.

Các vấn đề liên quan