Ruby on rails Ruby正则表达式匹配一个换行符,后跟除以外的任何字符(3个大写字符,后跟一个管道)

Ruby on rails Ruby正则表达式匹配一个换行符,后跟除以外的任何字符(3个大写字符,后跟一个管道),ruby-on-rails,ruby,regex,sublimetext,Ruby On Rails,Ruby,Regex,Sublimetext,(希望)这里有一个简单的正则表达式问题。我希望匹配一个或多个没有后跟三个大写字符和一个管道(|)的特定模式的新行,并将其删除 举个例子,我想把这个转变为: foo bar foo bar. Normal 0 false false false EN-US JA X-NONE foo bar foo bar |||||HH OBX|156|TX|foo bar|||N OBX|157|TX|foo bar 为此: foo bar foo bar. Nor

(希望)这里有一个简单的正则表达式问题。我希望匹配一个或多个没有后跟三个大写字符和一个管道(
|
)的特定模式的新行,并将其删除

举个例子,我想把这个转变为:

foo bar foo bar.



Normal

0

false

false

false



EN-US

JA


X-NONE




foo bar foo bar




|||||HH
OBX|156|TX|foo bar|||N
OBX|157|TX|foo bar
为此:

foo bar foo bar. Normal  0 false  false false  EN-US JA  X-NONE|||||HH
OBX|156|TX|foo bar|||N
OBX|157|TX|foo bar
我这里有一个在Sublime中非常有效的正则表达式:

(\n+)(?!MSH|PID|NTE|PV1|RXO|ORC|DG1|OBR|OBX).*
但在ruby中,它并没有消除换行符。在将Supreme正则表达式转换为rails正则表达式时,我缺少了什么

@r.force_encoding("UTF-8").gsub("\r\n","\r").gsub("(\r+)(?!MSH|PID|NTE|PV1|RXO|ORC|DG1|OBR|OBX)(.*)"," $2")

str=
str=我的解决方案是单独处理行,多行正则表达式可能会让很多人感到困惑

.每行或.行都返回单独的行

.grep将根据正则表达式或基于字符串的模式匹配数组

.join将获取单独的行并从结果中返回单个多行字符串

str.each_line
   .grep( /^[A-Z]{3,3}\|.+/ )
   .join( '' )
至于正则表达式,让我们也来分解一下,现在我们只逐行处理事情:

^      - Starting at the beginning of the line.
[A-Z]  - Only match the range of chars from 'A' to 'Z' ( all cap chars ).
{3, 3} - Match only 3 chars, no more, no less.
\|     - Followed by a '|' char.
.+     - Followed by 1+ chars of anything.

我的解决方案是单独处理行,多行正则表达式可能会让很多人感到困惑

.每行或.行都返回单独的行

.grep将根据正则表达式或基于字符串的模式匹配数组

.join将获取单独的行并从结果中返回单个多行字符串

str.each_line
   .grep( /^[A-Z]{3,3}\|.+/ )
   .join( '' )
至于正则表达式,让我们也来分解一下,现在我们只逐行处理事情:

^      - Starting at the beginning of the line.
[A-Z]  - Only match the range of chars from 'A' to 'Z' ( all cap chars ).
{3, 3} - Match only 3 chars, no more, no less.
\|     - Followed by a '|' char.
.+     - Followed by 1+ chars of anything.

如果
str
是您的字符串

r = /
    \n+                        # match one or more newlines
    (?!                        # start a negative lookahead
      #{Regexp.union(keepers)} # match one of keepers
      \|                       # match pipe--escape required
    )                          # close negative lookahead 
    /x                         # extended/free-spacing regex definition mode
  #=> /
      \n+
      (?!
        (?-mix:MSH|PID|NTE|PV1|RXO|ORC|DG1|OBR|OBX)
        \|
      )
      /x 

keepers = %w[ MSH PID NTE PV1 RXO ORC DG1 OBR OBX ]
  #=> ["MSH", "PID", "NTE", "PV1", "RXO", "ORC", "DG1", "OBR", "OBX"] 

puts str.gsub(r, "")
  # foo bar foo bar.Normal0falsefalsefalseEN-USJAX-NONEfoo bar foo bar|||||HH
  # OBX|156|TX|foo bar|||N
  # OBX|157|TX|foo bar

如果
str
是您的字符串

r = /
    \n+                        # match one or more newlines
    (?!                        # start a negative lookahead
      #{Regexp.union(keepers)} # match one of keepers
      \|                       # match pipe--escape required
    )                          # close negative lookahead 
    /x                         # extended/free-spacing regex definition mode
  #=> /
      \n+
      (?!
        (?-mix:MSH|PID|NTE|PV1|RXO|ORC|DG1|OBR|OBX)
        \|
      )
      /x 

keepers = %w[ MSH PID NTE PV1 RXO ORC DG1 OBR OBX ]
  #=> ["MSH", "PID", "NTE", "PV1", "RXO", "ORC", "DG1", "OBR", "OBX"] 

puts str.gsub(r, "")
  # foo bar foo bar.Normal0falsefalsefalseEN-USJAX-NONEfoo bar foo bar|||||HH
  # OBX|156|TX|foo bar|||N
  # OBX|157|TX|foo bar

您是否尝试过将正则表达式表示为regexp而不是字符串?也就是说:
gsub(/(\r+)…/)
而不是
gsub((\r+)
你可以简化正则表达式,比如:
\n+(?!([A-Z]{3})。*)
。我不明白你想要的输出的第一行为什么不是
foo bar foo bar foo bar.normal0falseFalseen-USJAX-NONEfoo bar foo bar foo bar
。也就是说,为什么新行组转换为空格(为什么有时有一个空格,有时有两个空格)以及第二个
“foo-bar-foo-bar”
?Cary Swoveland,我有点匆忙地做了这个例子,本质上我只想将一个或多个新行组转换为一个空格@archana和@tadman通过使用
/
而不是字符串获得了成功。您应该进行编辑以更正所需的输出,因为您的问题虽然得到了回答,但将来可能会被许多人阅读。您是否尝试过将正则表达式表示为regexp而不是字符串?也就是说:
gsub(/(\r+)…/)
而不是
gsub((\r+)
你可以简化正则表达式,比如:
\n+(?!([A-Z]{3})。*)
。我不明白你想要的输出的第一行为什么不是
foo bar foo bar foo bar.normal0falseFalseen-USJAX-NONEfoo bar foo bar foo bar
。也就是说,为什么新行组转换为空格(为什么有时有一个空格,有时有两个空格)以及第二个
“foo-bar-foo-bar”
?Cary Swoveland,我有点匆忙地做了这个例子,本质上我只想将一个或多个新行组转换为一个空格@archana和@tadman通过使用
/
而不是字符串实现了这一点。您应该编辑以更正所需的输出,因为您的问题虽然得到了回答,但将来可能会被许多人阅读。这个答案对我很有效,但您能解释一下为什么您的答案比我的答案更有效吗?
/
的行为是否与引号不同?您的正则表达式是一种模式。引号中的任何内容都是字符串而不是模式。请阅读这里:。在本文档中,“模式通常是一个Regexp;如果作为字符串给出,它包含的任何正则表达式元字符都将被逐字解释,例如,\\d'将匹配后跟“d”的齿隙,而不是数字。“if
str=“abc\nOSBxyz”
r=/(\n+)(!MSH | PID | NTE PV1 | RXO | ORC | DG1 | OBR | OBX)。*/
str(r,,)#=>“abc”
,但它应该返回
“abcOSBxyz”
,因为
“OSB”
后面没有管道。如果
str=“abc\nOSB | xyz”
str.gsub(r,,)#=>“abc”
,但在这种情况下,它应该返回
str
。这个答案对我有效,但你能解释为什么你的答案对我有效吗?
/
的行为与引号不同吗?你的正则表达式是一个模式。引号内的任何内容都是字符串而不是模式。请阅读此处:。来自此文档“模式通常是一个Regexp;如果作为字符串给出,它包含的任何正则表达式元字符都将被逐字解释,例如,\\d'将匹配后跟“d”的齿隙,而不是数字。”如果
str=“abc\nOSBxyz”
r=/(\n+)(!MSH | PID | NTE PV1 | RXO | ORC | DG1 | OBR | OBX)。*/
str gsub“
,但它应该返回
“abcOSBxyz”
,因为
“OSB”
后面没有管道。如果
str=“abc\nOSB | xyz”
str.gsub(r),)#=>“abc”
,但在这种情况下它应该返回
str
。有一个问题:
“abc”。每行grep(/[a-Z]{3,3}.+>。”两件小事:
{3,3}
{3}
相同,
join(“”)
join
相同。我更喜欢显式。有一个问题:
“abc”。每行.grep(/^[a-Z]{3,3}.+/).join(“”)#=>”
。两件小事:
{3
{3}/code>与
相同
join
相同。我更喜欢明确。