একাধিক ক্যাপচার-গ্রুপগুলির সাথে আরে রেগেক্স গ্রুপ ক্যাপচার


95

আর-তে, নিয়মিত অভিব্যক্তি ম্যাচ থেকে গ্রুপ ক্যাপচারটি নিষ্কাশন করা কি সম্ভব? যতদুর আমি বলতে যেমন করতে পারেন, কেউ grep, grepl, regexpr, gregexpr, sub, অথবা gsubগ্রুপ যেমনটি ফিরে যান।

আমাকে এ জাতীয়ভাবে এনকোড করা স্ট্রিংগুলি থেকে মূল-মান জোড়গুলি বের করতে হবে:

\((.*?) :: (0\.[0-9]+)\)

আমি সবসময় কেবল একাধিক ফুল-ম্যাচ গ্রেপ করতে পারি, বা বাইরে (নন-আর) প্রসেসিংয়ের বাইরে কিছু করতে পারি, তবে আমি আশা করছিলাম যে এটি আর এর মধ্যেই সব করতে পারব Is এমন কোনও ফাংশন বা প্যাকেজ রয়েছে যা এটি করার জন্য এই জাতীয় ফাংশন সরবরাহ করে?

উত্তর:


119

str_match(), stringrপ্যাকেজ থেকে , এটি করবে। এটি ম্যাচের প্রতিটি গ্রুপের জন্য একটি কলাম সহ একটি অক্ষর ম্যাট্রিক্স প্রদান করে (এবং পুরো ম্যাচের জন্য একটি):

> s = c("(sometext :: 0.1231313213)", "(moretext :: 0.111222)")
> str_match(s, "\\((.*?) :: (0\\.[0-9]+)\\)")
     [,1]                         [,2]       [,3]          
[1,] "(sometext :: 0.1231313213)" "sometext" "0.1231313213"
[2,] "(moretext :: 0.111222)"     "moretext" "0.111222"    

4
এবং str_match_all()একটি গ্রুপে সমস্ত গ্রুপের সাথে মেলে
স্মি

আমি কীভাবে কেবল [, 1] এর জন্য কেবল বন্দী গোষ্ঠীগুলি মুদ্রণ করতে পারি?
নেনুর

নিশ্চিত হতে পারছি না তুমি আসলে কি খুঁজছ. বন্দী গোষ্ঠীগুলি 2 এবং 3 কলামের [,1]সম্পূর্ণ ম্যাচ। [,2:3]বন্দী গোষ্ঠী হয়।
কেন্ট জনসন

52

gsub এটি করে, আপনার উদাহরণ থেকে:

gsub("\\((.*?) :: (0\\.[0-9]+)\\)","\\1 \\2", "(sometext :: 0.1231313213)")
[1] "sometext 0.1231313213"

আপনাকে উদ্ধৃতিগুলিতে দ্বিগুণভাবে পালাতে হবে তবে তারা রেজেজের জন্য কাজ করবে।

আশাকরি এটা সাহায্য করবে.


আসলে ডেটা.ফ্রেমে রাখার জন্য আমাকে ক্যাপচার করা সাবস্ট্রিংগুলি বের করতে হবে। তবে, আপনার উত্তরটির দিকে তাকিয়ে আমি অনুমান করি যে আমি কী চান তা পেতে আমি জিএসব এবং কয়েকটি স্টারস্প্লিটের শৃঙ্খলা তৈরি করতে পারি, সম্ভবত: স্টারস্প্লিট (স্টারস্প্লিট (জিএসব (রেজেক্স, "\\ 1 :: \\ 2 ::::" ", স্ট্রিং) ), "::::") [[1]], "::")
ড্যানিয়েল ডিকিসন

9
দুর্দান্ত আর gsubম্যানপেজটি খুব খারাপভাবে একটি উদাহরণ প্রয়োজন যা দেখায় যে ক্যাপচার-গ্রুপের রেফারেন্স থেকে বাঁচতে আপনার '\\ 1' প্রয়োজন।
smci

35

চেষ্টা করুন regmatches()এবং regexec():

regmatches("(sometext :: 0.1231313213)",regexec("\\((.*?) :: (0\\.[0-9]+)\\)","(sometext :: 0.1231313213)"))
[[1]]
[1] "(sometext :: 0.1231313213)" "sometext"                   "0.1231313213"

4
ভ্যানিলা আর সমাধানের জন্য এবং regmatchesযেটি আমি এর আগে কখনও দেখিনি তা নির্দেশ করার জন্য ধন্যবাদ
অ্যান্ডি

আপনি দুবার স্ট্রিং লিখতে হবে কেন?
স্টেফানো বোরিনি

4
@ স্টেফানোবোরিনী regexecকেবল ম্যাচের অবস্থান সম্পর্কিত তথ্য সম্বলিত একটি তালিকা ফিরিয়ে দেয়, সুতরাং regmatchesব্যবহারকারীকে ম্যাচের তালিকার সাথে সম্পর্কিত স্ট্রিং সরবরাহ করতে হবে।
আরটিবিকার্ড

19

gsub () এটি করতে পারে এবং কেবল ক্যাপচার গ্রুপকে ফিরিয়ে দিতে পারে:

তবে এটি কাজ করার জন্য, gsub () সহায়তা হিসাবে উল্লিখিত হিসাবে আপনাকে অবশ্যই আপনার ক্যাপচার গোষ্ঠীর বাইরে উপাদানগুলি স্পষ্টভাবে নির্বাচন করতে হবে।

(...) অক্ষর ভেক্টরগুলির এক্স 'এক্স' যা প্রতিস্থাপিত হয় না তাদের অপরিবর্তনীয় ফিরিয়ে দেওয়া হবে।

সুতরাং আপনার পাঠ্যটি নির্বাচিত হওয়ার জন্য যদি কিছু স্ট্রিংয়ের মাঝখানে থাকে, যোগ করে * * ক্যাপচার গোষ্ঠীর আগে এবং পরে আপনাকে কেবল এটি ফেরত দেওয়ার অনুমতি দেওয়া উচিত।

gsub(".*\\((.*?) :: (0\\.[0-9]+)\\).*","\\1 \\2", "(sometext :: 0.1231313213)") [1] "sometext 0.1231313213"


4

আমি পার্ল সুসংগত নিয়মিত প্রকাশ করতে চাই। সম্ভবত অন্য কেউও করেন ...

এখানে এমন একটি ফাংশন রয়েছে যা পার্লের সাথে সামঞ্জস্যপূর্ণ নিয়মিত এক্সপ্রেশন করে এবং আমি যে ভাষাতে ব্যবহৃত হয় সেগুলিতে ফাংশনগুলির কার্যকারিতার সাথে মেলে:

regexpr_perl <- function(expr, str) {
  match <- regexpr(expr, str, perl=T)
  matches <- character(0)
  if (attr(match, 'match.length') >= 0) {
    capture_start <- attr(match, 'capture.start')
    capture_length <- attr(match, 'capture.length')
    total_matches <- 1 + length(capture_start)
    matches <- character(total_matches)
    matches[1] <- substr(str, match, match + attr(match, 'match.length') - 1)
    if (length(capture_start) > 1) {
      for (i in 1:length(capture_start)) {
        matches[i + 1] <- substr(str, capture_start[[i]], capture_start[[i]] + capture_length[[i]] - 1)
      }
    }
  }
  matches
}

3

এইভাবেই আমি এই সমস্যাটি ঘিরে কাজ শেষ করেছি। আমি প্রথম এবং দ্বিতীয় ক্যাপচার গ্রুপগুলির সাথে মেলে এবং দুটি gregexprকল চালানোর জন্য দুটি পৃথক রেজিক্স ব্যবহার করেছি, তারপরে ম্যাচ সাবস্ট্রিংগুলি টেনে আনলাম :

regex.string <- "(?<=\\().*?(?= :: )"
regex.number <- "(?<= :: )\\d\\.\\d+"

match.string <- gregexpr(regex.string, str, perl=T)[[1]]
match.number <- gregexpr(regex.number, str, perl=T)[[1]]

strings <- mapply(function (start, len) substr(str, start, start+len-1),
                  match.string,
                  attr(match.string, "match.length"))
numbers <- mapply(function (start, len) as.numeric(substr(str, start, start+len-1)),
                  match.number,
                  attr(match.number, "match.length"))

একটি কার্যকারী কোডের জন্য +1 যাইহোক, আমি বরং আর থেকে একটি দ্রুত শেল কমান্ড expr "xyx0.0023xyxy" : '[^0-9]*\([.0-9]\+\)'
চালাতাম

3

সঙ্গে সলিউশন strcaptureথেকে utils:

x <- c("key1 :: 0.01",
       "key2 :: 0.02")
strcapture(pattern = "(.*) :: (0\\.[0-9]+)",
           x = x,
           proto = list(key = character(), value = double()))
#>    key value
#> 1 key1  0.01
#> 2 key2  0.02

2

stringrপ্যাকেজে প্রস্তাবিত হিসাবে , এটি হয় str_match()বা ব্যবহার করে অর্জন করা যেতে পারে str_extract()

ম্যানুয়াল থেকে অভিযোজিত:

library(stringr)

strings <- c(" 219 733 8965", "329-293-8753 ", "banana", 
             "239 923 8115 and 842 566 4692",
             "Work: 579-499-7527", "$1000",
             "Home: 543.355.3679")
phone <- "([2-9][0-9]{2})[- .]([0-9]{3})[- .]([0-9]{4})"

আমাদের গ্রুপগুলি উত্তোলন এবং একত্রিত করা:

str_extract_all(strings, phone, simplify=T)
#      [,1]           [,2]          
# [1,] "219 733 8965" ""            
# [2,] "329-293-8753" ""            
# [3,] ""             ""            
# [4,] "239 923 8115" "842 566 4692"
# [5,] "579-499-7527" ""            
# [6,] ""             ""            
# [7,] "543.355.3679" ""   

একটি আউটপুট ম্যাট্রিক্স সহ গোষ্ঠীগুলি নির্দেশ করে (আমরা কলাম 2+ এ আগ্রহী):

str_match_all(strings, phone)
# [[1]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "219 733 8965" "219" "733" "8965"
# 
# [[2]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "329-293-8753" "329" "293" "8753"
# 
# [[3]]
#      [,1] [,2] [,3] [,4]
# 
# [[4]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "239 923 8115" "239" "923" "8115"
# [2,] "842 566 4692" "842" "566" "4692"
# 
# [[5]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "579-499-7527" "579" "499" "7527"
# 
# [[6]]
#      [,1] [,2] [,3] [,4]
# 
# [[7]]
#      [,1]           [,2]  [,3]  [,4]  
# [1,] "543.355.3679" "543" "355" "3679"

842 566 4692 সম্পর্কে
ফেরোয়াও

বাদ দেওয়ার জন্য ধন্যবাদ। _allপ্রাসঙ্গিক stringrফাংশনগুলির জন্য প্রত্যয় ব্যবহার করে সংশোধন করা হয়েছে ।
মেগাট্রন

0

এটি নির্বাচিত উত্তর থেকে উদাহরণ গ্রহণ করে প্যাকেজটি অনুরুচ ব্যবহার করে করা যেতে পারে :

# install.packages("unglue")
library(unglue)

s <- c("(sometext :: 0.1231313213)", "(moretext :: 0.111222)")
unglue_data(s, "({x} :: {y})")
#>          x            y
#> 1 sometext 0.1231313213
#> 2 moretext     0.111222

বা একটি ডেটা ফ্রেম থেকে শুরু

df <- data.frame(col = s)
unglue_unnest(df, col, "({x} :: {y})",remove = FALSE)
#>                          col        x            y
#> 1 (sometext :: 0.1231313213) sometext 0.1231313213
#> 2     (moretext :: 0.111222) moretext     0.111222

আপনি নামকৃত ক্যাপচার সহ optionচ্ছিক প্যাটার্ন থেকে কাঁচা রেজেক্স পেতে পারেন:

unglue_regex("({x} :: {y})")
#>             ({x} :: {y}) 
#> "^\\((.*?) :: (.*?)\\)$"

unglue_regex("({x} :: {y})",named_capture = TRUE)
#>                     ({x} :: {y}) 
#> "^\\((?<x>.*?) :: (?<y>.*?)\\)$"

আরও তথ্য: https://github.com/moodymudskipper/unglue/blob/master/README.md

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.