案例匹配查找替换


14

以三个输入,文本串T; 一串要替换的字符F;以及用替换它们的字符串R。对于每个T具有相同(不区分大小写)字符的子字符串F,请将其替换为中的字符R。但是,请保持与原始文本相同的大小写。

如果输入的字符R多于个F,则多余的字符应与输入的大小写相同R。如果其中包含数字或符号F,则其中的相应字符R应保持其大小写RF不一定会出现在中T

您可以假设所有文本都在可打印的ASCII范围内。

例子

"Text input", "text", "test" -> "Test input"

"tHiS Is a PiEcE oF tExT", "is", "abcde" -> "tHaBcde Abcde a PiEcE oF tExT"

"The birch canoe slid on the smooth planks", "o", " OH MY " -> "The birch can OH MY e slid  OH MY n the sm OH MY  OH MY th planks"

"The score was 10 to 5", "10", "tEn" -> "The score was tEn to 5"

"I wrote my code in Brain$#@!", "$#@!", "Friend" -> "I wrote my code in BrainFriend"

"This challenge was created by Andrew Piliser", "Andrew Piliser", "Martin Ender" -> "This challenge was created by Martin Ender"

// Has a match, but does not match case 
"John does not know", "John Doe", "Jane Doe" -> "Jane does not know"

// No match
"Glue the sheet to the dark blue background", "Glue the sheet to the dark-blue background", "foo" -> "Glue the sheet to the dark blue background"

// Only take full matches
"aaa", "aa", "b" -> "ba"

// Apply matching once across the string as a whole, do not iterate on replaced text
"aaaa", "aa", "a" -> "aa"

"TeXT input", "text", "test" -> "TeST input"

沙盒链接


要求提供一个奇怪的套管示例:"TeXT input", "text", "test"
工程师Toast,

@EngineerToast添加示例
Andrew

不确定为什么我会"The birch canoe slid on the smooth planks", "o", " OH MY "这么幽默,但是我喜欢那个例子。
魔术章鱼缸

Answers:


3

视网膜,116字节

i`(.+)(?=.*¶\1(¶.*)$)|.*¶.*$
¶¶$2¶$1¶¶
{T`l`L`¶¶.(?=.*¶[A-Z])
T`L`l`¶¶.(?=.*¶[a-z])
}`¶¶¶(.)(.*¶).
$1¶¶¶$2
¶¶¶¶.*|¶

在线尝试!说明:

i`(.+)(?=.*¶\1(¶.*)$)|.*¶.*$
¶¶$2¶$1¶¶

进行搜索,T并且每当对匹配项的前瞻存在不区分大小写的匹配时F,都会用一堆换行符包围,并且R还会插入to的前瞻性。

{T`l`L`¶¶.(?=.*¶[A-Z])
T`L`l`¶¶.(?=.*¶[a-z])
}`¶¶¶(.)(.*¶).
$1¶¶¶$2

R调整副本的每个字母以防与匹配的字母匹配,然后将其移出工作区域,以便可以处理下一个字母,直到副本R或匹配用尽字母。

¶¶¶¶.*|¶

如果副本的R字母用尽,则比赛的其余部分将以4个换行符开头,因此将其删除。否则,剩下的将是剩下的副本R,需要将其副本与输入的不匹配部分连接起来以产生结果。


3

APL(Dyalog)75 73 72字节

提示输入TR以及F按照这个顺序。R必须b以Dyalog转换格式给出,并且F必须以PCRE格式给出。

⍞⎕R(⍞∘{(⊣⌿d)l¨⍨(1∘⌷≠(⊢⌿d∊⎕A,lA)∧≠⌿)d≠(l819⌶)d←↑⍺⍵.Match↑¨⍨≢⍺})⍠1⊢⍞

在线尝试!

 提示输入 T

 产生(分别为1和T

⍞⎕R(... )⍠1 提示F[R用下面的函数的结果E放置比赛:

⍞∘{…} 通过将提示符R为左的参数绑定到以下项来派生单子函数:

  ≢⍺ 计算中的字母数 R

  ⍺⍵.Match↑¨⍨ 取每个字母中的那么多字母R,则匹配项
   为左参数,我们将其绑定R为。
   是一个名称空间,其中Match包含当前找到的字符串。

   将这两个混合成两行矩阵

  d← 存储为 d

  (…… )  对此应用以下默认功能:

   819⌶ 小写(助记符:819看起来像Big

   l← 将该功能存储为 l

  d≠ 布尔值d不同(即,每个小写/大写字母为0/1)

  (…… ) 对此应用以下默认功能:

   ≠⌿ 垂直异或

   ()∧ 与以下数组的布尔AND:

    l⎕A 小写的一个 lphabet

    ⎕A, 在前面加上大写一个 lphabet

    d∊ d中每个字母的布尔值是否为该字母的成员(即是否为字母)

    ⊢⌿ 最后一行,即匹配字符是否为字母

   1∘⌷≠ 与第一行进行XOR,即的每个字符是否R为大写

  ()l¨⍨ 用它来小写(如果为0)或大写(如果为1)的每个字母:

   ⊣⌿ 第一行,即 R


* Dyalog Classic使用⎕OPT 代替的字节数



2

撤销。Dom的答案远胜于此。

Perl 5中,136 + 1(-p)= 137字节

$f=<>;chomp$f;@R=($r=<>)=~/./g;for$i(/\Q$f/gi){$c=$n='';$"=$R[$c++],$n.=/[A-Z]/?uc$":/[a-z]/?lc$":$"for$i=~/./g;s/\Q$i/$n.substr$r,$c/e}

在线尝试!

@Dom Hastings提到后大幅削减 \Q

Perl 5中,176 + 1(-p)= 177字节

sub h($){chomp@_;pop=~s/[^a-z0-9 ]/\\$&/gir}$f=h<>;@R=($r=<>)=~/./g;for$i(/$f/gi){$c=$n='';$"=$R[$c++],$n.=/[A-Z]/?uc$":/[a-z]/?lc$":$"for$i=~/./g;$i=h$i;s/$i/$n.substr$r,$c/e}

在线尝试!


现在通过所有测试用例;)108:在线尝试!
Dom Hastings

您应该发布它。它比我的要好很多。
Xcali

很公平!制作起来很有趣。我喜欢挑战!
Dom Hastings

2

PowerShell,190字节

param($T,$F,$R)[regex]::Replace($T,'(?i)'+[regex]::escape($F),{param($m)-join(0..$R.Length|%{(($y=$R[$_]),("$y"."To$((('Low','Upp')[($z="$m"[$_])-cmatch($C='[A-Z]')]))er"()))[$z-match$C]})})

在线尝试!

说明:

[Regex]::Replace( 
    input text T,
    Find text F with case insensitive and [regex]::escape() for symbols,
    {scriptblock} for computing the replacement
)

替换脚本块执行以下操作:

$m is the matched text with case information
loop over each character in R as $y
    $z is the same index character in $m ($null if R overruns)
    $z-match'[A-Z]' checks if alphabetic, so we must to case-match
      otherwise, non-alphabetic or null, no case-match, return $y unchanged.
    if case-matching, check if z case-sensitive matches '[A-Z]' and
      use dynamic method calling from a generated string, either 
      $y."ToLower"()
      $y."ToUpper"()
      to force the match
-join the loop output into a replacement string

测试用例:

function f {
param($T,$F,$R)[regex]::Replace($T,'(?i)'+[regex]::escape($F),{param($m)-join(0..$R.Length|%{(($y=$R[$_]),("$y"."To$((('Low','Upp')[($z="$m"[$_])-cmatch($C='[A-Z]')]))er"()))[$z-match$C]})})
}

Import-Module Pester

$Cases = @(
    @{Text = "Text input"; Find = "text"; Replace = "test"; Result = "Test input" }
    @{Text = "tHiS Is a PiEcE oF tExT"; Find = "is"; Replace = "abcde"; Result = "tHaBcde Abcde a PiEcE oF tExT" }
    @{Text = "The birch canoe slid on the smooth planks"; Find = "o"; Replace = " OH MY "; Result = "The birch can OH MY e slid  OH MY n the sm OH MY  OH MY th planks" }
    @{Text = "The score was 10 to 5"; Find = "10"; Replace = "tEn"; Result = "The score was tEn to 5" }
    @{Text = "I wrote my code in Brain$#@!"; Find = "$#@!"; Replace = "Friend"; Result = "I wrote my code in BrainFriend" }
    @{Text = "This challenge was created by Andrew Piliser"; Find = "Andrew Piliser"; Replace = "Martin Ender"; Result = "This challenge was created by Martin Ender" }
    @{Text = "John does not know"; Find = "John Doe"; Replace = "Jane Doe" ; Result ="Jane does not know" }
    @{Text = "Glue the sheet to the dark blue background"; Find = "Glue the sheet to the dark-blue background"; Replace = "foo"; Result ="Glue the sheet to the dark blue background" }
    @{Text = "aaa" ; Find = "aa"; Replace = "b"; Result ="ba" }
    @{Text = "aaaa"; Find = "aa"; Replace = "a"; Result ="aa" }
    @{Text = "TeXT input"; Find = "text"; Replace = "test"; Result ="TeST input" }
)

Describe "Tests" {

    It "works on /<Text>/<Find>/<Replace>/ == '<Result>'" -TestCases $Cases {
        param($Text, $Find, $Replace, $Result)
        f $Text $Find $Replace | Should -BeExactly $Result
    }

}

1

TXR Lisp,285个字节

(defun f(s f r)(let*((w(copy s))(x(regex-compile ^(compound,(upcase-str f))))(m(reverse(tok-where(upcase-str s)x))))(each((n m))(set[w n]r) (for((i(from n)))((< i (min(to n)(len w))))((inc i))(cond((chr-isupper[s i])(upd[w i]chr-toupper))((chr-islower[s i])(upd[w i]chr-tolower)))))w))

常规格式的原件:

(defun f (s f r)
  (let* ((w (copy s))
         (x (regex-compile ^(compound ,(upcase-str f))))
         (m (reverse (tok-where (upcase-str s) x))))
    (each ((n m))
      (set [w n] r)
      (for ((i (from n))) ((< i (min (to n) (len w)))) ((inc i))
        (cond ((chr-isupper [s i]) (upd [w i] chr-toupper))
              ((chr-islower [s i]) (upd [w i] chr-tolower)))))
    w))

1

JavaScript,177字节

(T,F,R)=>T.replace(eval(`/${F.replace(/[-\/\\^$*+?.()|[\]{}]/g,'\\$&')}/gi`),F=>[...R].map((r,i)=>/[A-Z]/i.test(f=F[i]||'')?r[`to${f>'`'&&f<'{'?'Low':'Upp'}erCase`]():r).join``)

少打高尔夫球:

(T,F,R) => T.replace(
    eval(`/${F.replace(/[-\/\\^$*+?.()|[\]{}]/g,'\\$&')}/gi`),
    F=>[...R].map((r,i) =>
        /[A-Z]/i.test(f = F[i] || '')
            ? r[`to${
                f > '`' && f < '{'
                    ? 'Low'
                    : 'Upp'
                }erCase`]()
            : r
    ).join``
)

由于程序必须处理符号,因此此正则表达式转义函数提供了47个字节。:(


1

Python 2中193个 200字节

T,F,R=input()
w=str.lower
i=-len(T)
l=len(F)
T+=' '
while i:
 s=T[i:i+l]
 if w(s)==w(F):T=T[:i]+`[[y,[w(y),y.upper()][x<'a']][x.isalpha()]for x,y in zip(s,R)]`[2::5]+R[l:]+T[i+l:];i+=l-1
 i+=1
print T

在线尝试!


这(193个字节,来自TIO链接)将无法在字符串末尾找到匹配项。
tehtmi

1

Python 3,183字节

import re
j="".join
f=lambda T,F,R:j((p,j((y,(y.lower(),y.upper())[x<'a'])[x.isalpha()]for(x,y)in zip(p,R))+R[len(F):])[i%2>0]for i,p in enumerate(re.split('('+re.escape(F)+')',T,0,2)))

在线尝试!

re.split +保留所有偶数元素,并通过替换字符串的正确转换替换所有奇数元素:

>>> re.split("(is)","tHiS Is a PiEcE oF tExT",0,2) # 2=re.IGNORE_CASE
['tH', 'iS', ' ', 'Is', ' a PiEcE oF tExT']

1

C(GCC) 210 211 207 189字节

必须添加一个字节来修复“ BrainFriend”测试用例大写的错误

哇,这很乏味...现在打高尔夫球

char*c,*p;d,l;f(t,f,r){for(d=isalpha(*(p=f)),p=c=t;c=strcasestr(c,f);p=c+=l>0?l:0){for(l=strlen(f);p<c;)putchar(*p++);for(p=r;*p;p++,c+=l-->0)putchar(d*l<1?*p:*c&32?*p|32:*p&~32);}puts(p);}

在线尝试!


我可能会遗漏一些显而易见的东西,但是为什么刚*(p=f)设置完p=c=t之后又需要?我只是尝试了一下*f,但没有用,所以不会立即被覆盖。
安德鲁

f是befault的int值,因此我们不能取消引用它以获得字符,但是p是字符*
cleblanc

嗯,那很有道理。因此,这是一种较短的书写方式*((char*)f)?凉!
安德鲁

1

C#(Mono C#编译器),241字节

using System.Text.RegularExpressions;
class Program {
static void Main(string[] args) {
r("Text input","text","Test");
}
static void r(string v,string i,string u)
{
System.Console.WriteLine(Regex.Replace(v,i,u,RegexOptions.IgnoreCase)); 
}
}

在线尝试!


1
欢迎来到PPCG!您可以在此处删除相当多的空格,实际上您需要将输入作为参数或输入(禁止在其中进行编码),或者实际上可以包括该函数;您甚至都不需要该Action<string,string,string> r =零件
HyperNeutrino
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.