2013-06-06 23 views
9

Dưới đây là chuỗi của tôi:Regex - Bỏ qua một số bộ phận của chuỗi trong trận đấu

address='St Marks Church',notes='The North East\'s premier...' 

Các regex Tôi đang sử dụng để lấy các phần khác nhau sử dụng match_all

'/(address|notes)='(.+?)'/i' 

Kết quả là:

địa chỉ => Nhà thờ St Marks
ghi chú => Đông Bắc \

Tôi làm cách nào để bỏ qua ký tự \ 'cho ghi chú?

+1

Bạn có muốn chỉ xem xét các ký tự chữ và số trong biểu thức của mình không? –

+0

Không có bất cứ điều gì về cơ bản giữa 'và thứ hai' ngoại trừ \ '. Tôi là một chút của một newbie regex Tôi sợ vì vậy có lẽ có bit đầu tiên sai? –

Trả lời

4

Không chắc chắn nếu bạn đang quấn chuỗi của bạn với heredoc hoặc dấu ngoặc kép, nhưng cách tiếp cận ít tham lam:

$str4 = 'address="St Marks Church",notes="The North East\'s premier..."'; 
preg_match_all('~(address|notes)="([^"]*)"~i',$str4,$matches); 
print_r($matches); 

Output

Array 
(
    [0] => Array 
     (
      [0] => address="St Marks Church" 
      [1] => notes="The North East's premier..." 
     ) 

    [1] => Array 
     (
      [0] => address 
      [1] => notes 
     ) 

    [2] => Array 
     (
      [0] => St Marks Church 
      [1] => The North East's premier... 
     ) 

) 

Một phương pháp với preg_split:

//split the string at the comma 
//assumes no commas in text 
$parts = preg_split('!,!', $string); 
foreach($parts as $key=>$value){ 
    //split the values at the = sign 
    $parts[$key]=preg_split('!=!',$value); 
    foreach($parts[$key] as $k2=>$v2){ 
     //trim the quotes out and remove the slashes 
     $parts[$key][$k2]=stripslashes(trim($v2,"'")); 
    } 
} 

Đầu ra có dạng:

Array 
(
    [0] => Array 
     (
      [0] => address 
      [1] => St Marks Church 
     ) 

    [1] => Array 
     (
      [0] => notes 
      [1] => The North East's premier... 
     ) 

) 

siêu chậm phương pháp cũ-Skool:

$len = strlen($string); 
$key = ""; 
$value = ""; 
$store = array(); 
$pos = 0; 
$mode = 'key'; 
while($pos < $len){ 
    switch($string[$pos]){ 
    case $string[$pos]==='=': 
     $mode = 'value'; 
     break; 
    case $string[$pos]===",": 
     $store[$key]=trim($value,"'"); 
     $key=$value=''; 
     $mode = 'key'; 
     break; 
    default: 
     $$mode .= $string[$pos]; 
    } 

    $pos++; 
} 
     $store[$key]=trim($value,"'"); 
+0

Phương pháp đầu tiên của bạn điều chỉnh chuỗi đầu vào cho phù hợp với phương pháp, phương pháp này nên được loại bỏ. Cách thứ hai sử dụng 'preg_split()' trong đó 'explode()' là lời gọi hàm hợp lý. Hơn nữa, nếu '\ '' có thể trong chuỗi, thì nó là công bằng để giả sử ',' và '=' cũng có thể. Thứ ba, tôi chưa thử nghiệm nhưng nó có lỗi đánh máy hoặc đang sử dụng các biến số cần tránh bất cứ khi nào có thể. – mickmackusa

+0

Tôi đã xóa bỏ phiếu giảm giá của mình vì tôi đánh giá cao việc bạn đang cố gắng sửa câu trả lời của mình. Đáng buồn thay, tôi cảm thấy tôi đã phải từ chối vì câu trả lời này cho thấy các phương pháp kém và/hoặc không đáng tin cậy. – mickmackusa

+0

Việc nhượng bộ các phương pháp lưu trữ dữ liệu không được khuyến khích.Luồng văn bản này phải được lưu trữ trong JSON, XML hoặc thậm chí là CSV và được xử lý với các phương pháp chuẩn công nghiệp một cách lý tưởng. Đánh giá cao ý kiến ​​của bạn. –

1

Bạn phải phù hợp với lên đến một trích dẫn kết thúc mà không được đi trước bởi một dấu chéo ngược như sau:

(address|notes)='(.*?)[^\\]' 

[^\\] Điều này buộc các nhân vật ngay trước 'nhân vật được bất cứ điều gì nhưng một dấu gạch chéo.

+0

Điều đó có hiệu quả nếu đầu vào là: '" address = '.', Notes = 'Thủ tướng của Đông Bắc ...' "'? – anubhava

+0

Như @anubhava ám chỉ, câu trả lời này là không chính xác và sẽ mangle giá trị trả về dự kiến. https://regex101.com/r/90fBSr/1 (downvoted là gây hiểu nhầm) – mickmackusa

1

Bởi vì bạn đã đăng rằng bạn đang sử dụng match_all và các thẻ hàng đầu trong hồ sơ của bạn là phpwordpress, tôi nghĩ rằng đó là công bằng để giả sử bạn đang sử dụng preg_match_all() với php.

Các mẫu sau đây sẽ phù hợp với chuỗi con cần thiết để buildyour mong muốn mảng kết hợp:

Patterns mà tạo ra một trận đấu fullstring và 1 nhóm chụp:

  1. /(address|notes)='\K(?:\\\'|[^'])*/ (166 bước, demo link)
  2. /(address|notes)='\K.*?(?=(?<!\\)')/ (218 bước, demo link)

Patterns mà tạo ra 2 nhóm chụp:

  1. /(address|notes)='((?:\\\'|[^'])*)/ (168 bước, demo link)
  2. /(address|notes)='(.*?(?<!\\))'/ (209 bước, demo link)

Code: (Demo)

$string="address='St Marks Church',notes='The North East\'s premier...'"; 

if(preg_match_all("/(address|notes)='\K(?:\\\'|[^'])*/",$string,$out)){ 
    $result=array_combine($out[1],$out[0]); 
} 
var_dump($result); 

echo "\n---\n"; 

if(preg_match_all("/(address|notes)='((?:\\\'|[^'])*)/",$string,$out,PREG_SET_ORDER)){ 
    $result=array_combine(array_column($out,1),array_column($out,2)); 
} 
var_dump($result); 

Output:

array(2) { 
    ["address"]=> 
    string(15) "St Marks Church" 
    ["notes"]=> 
    string(28) "The North East\'s premier..." 
} 

--- 
array(2) { 
    ["address"]=> 
    string(15) "St Marks Church" 
    ["notes"]=> 
    string(28) "The North East\'s premier..." 
} 

Mẫu # 1 và # 3 sử dụng lựa chọn thay thế để cho phép ký tự không phải dấu nháy đơn hoặc dấu nháy đơn không có dấu gạch chéo ngược.

Mẫu # 2 và # 4 (sẽ yêu cầu thêm dấu gạch chéo ngược khi được triển khai bằng php demo) sử dụng các giải pháp để đảm bảo rằng dấu nháy trước bởi dấu gạch chéo ngược không kết thúc.

Một số lưu ý:

  • Sử dụng các nhóm nắm bắt, lựa chọn thay thế, và lookarounds chi phí hiệu quả mô hình. Hạn chế việc sử dụng các thành phần này sẽ cải thiện hiệu suất. Sử dụng các lớp ký tự phủ định thường cải thiện hiệu suất.

  • Sử dụng \K (khởi động lại kết hợp chuỗi đầy đủ) hữu ích khi cố gắng giảm nhóm chụp và giảm kích thước của mảng đầu ra.

+0

@PaulPhillips hơn 4 năm sau, bạn có thể không còn là một newbie tại regex nữa. Vui lòng xem lại tất cả các câu trả lời trên trang này. Đáng buồn là các câu trả lời khác trên trang này là không chính xác/không chính xác và đã thu thập upvotes theo thời gian (có nghĩa là họ đã hiểu sai người đọc trong nhiều năm). Nếu bạn có bất kỳ câu hỏi nào về câu trả lời của tôi hoặc tại sao các câu trả lời khác không chính xác, tôi sẽ vui lòng giải thích. – mickmackusa

+0

Hey Mick bạn trolling câu trả lời trong quá khứ của mọi người hoặc chỉ của tôi? –

+0

Tôi đã xảy ra trên trang này trong khi nghiên cứu một câu hỏi khác trên một trang web StackExchange khác. Không có gì trollish về hành vi của tôi. Nếu tôi muốn trở thành một kẻ lừa đảo, tôi sẽ gọi cho bạn tên hoặc nhiều hơn chỉ đơn giản là không để lại một bình luận. Không, những gì tôi đã làm được xác định là một trang chứa 3 câu trả lời không chính xác (bây giờ 2 sau khi anubhava xóa), các câu trả lời không chính xác đã được giải thích sai, để lại lời giải thích (có liên kết demo), chỉnh sửa câu hỏi và cung cấp toàn diện và chu đáo câu trả lời. Những gì tôi đã làm chỉ nên xem xét "cải thiện nội dung". – mickmackusa

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