【问题标题】:Search a word boundary at a length and replace it with '|'搜索一个长度的单词边界并将其替换为“|”
【发布时间】:2015-10-27 21:19:59
【问题描述】:

我有一个超过 600 个字符的长字符串。我想用“|”替换长度小于 200 的单词边界。

我已使用以下代码来执行此操作。但是我没有运气。

data test;
   length str1 $200;
   str1 = "N=dddddd dddddd dddddd dddddddddd ddd ddddd dddddddd dd d ,n=,|t:14.2.2-1";
run;

data test1;
   set test;
   str01 = prxchange('s/\b/|/', -1, str1);
   str02 = prxchange('s/(.{20,}?\b).*/|/', -1, str1);
run;

我知道第一个会搜索所有单词边界并将它们替换为“|”,但我认为第二个会起作用。但后来只给了我'|'作为输出。

我正在寻找的是打破一个长脚注(超过 600 个字符)以分解为 4 行语句,因为行不能超过 200 个字符。所以我将长度不超过200的空格替换为'|'并使用 '|'

分解字符串

提前致谢!

在实时场景中,我有以下情况。

data test;
   length str1 $200;
   str1 = "XX XX XXXXX XXXX XXXXXXX XXX XXXXX X XXXXXX XXXXXXX XXXXXXXXX XX XXX XXXXXXXXX XXXXXXXXXXXX'X XXXXXX. XXXX XXXXXXXXX XX XXXXXXXXXX XXXXXXXXXX XXX XXXXXXXX. XXX XXXXXXX XXX XXXX XXXXXXXX XXXXXX XXXXXXXXXX XXX XXXXXXXXXX XXXX XXX XXXXX XXX XX XXXX XX XXXX XXXXXXX XXXXXXXXXX XXXXX XX XXX XXXXX XXX XXX XXXXX XX XXX XXXXXXXXXXX XXX XXXXXXXXXX XXXXX 11112525 65, XX XXXXX XXX XXXXXX XXX XXX XXX. XXXXXXXXXXXX, XXX XXXX XXXXX XXX XXXXX XXXXXXXX XXXX XXX XXXX XXXXXX XXXXXXXX XX "XXXXXXXX XXXXXXXX" XX XXX XXX XXXXXX XXX XXXX XXXXXXXXXXX XX XXXXXXXXXX XXXXX XX XXX XXX XXXXXXX XXXXXX. XXXX XX XX XXXX XXXXXX XXXXX XXXXXXXX XXXXX XXXXXXXX XXX XXXXXX XXXX XXXXXXXXXX XXXXXXXXXX XXX XXX XXXXXXXXXXXX XXXXXXX XXXXXXXXXX XXX XXXXXXXX XXXX. XXXXXXX, XXX XXXXXXX XXX XXXXXX XX "XXXXXXXX XXXXXXX - XX XXX XXXXXXX" XXX XXX XXXXXX XXXXX XXX XXX XXXXXXX XXXX XXXXXXX XXXXXXXXXX XXX XXXXXXXXXX X XXXXXXXXXXX XXXXXXXXXX XX XXXX XXXXX.  XXXXXXXXXXX XXXX XXXXXXXXX XXXX XXX XXXXXXX XXX XXXXXXXX X XXXXXXXXXX XXXXXXXXX, X XXXX XXX XXXX XX XXXXXX XXXXX, XXXXXXX XXXX XXXX XXXXXXXX XXXXXX XX XX XXXXXX XX XXXXXXXXX XXXXXX XXXXXXXX XXX XXXXXXXXXX XXXXXXX XX XXXXXXXXXX/XXXXXXXXXX XXX XXXXXXXX XXXXXXXXXX XX XXXXXXXX XXXXXXXX XX XXX XXX XXXXXX XX XXXXXX XXXX XXXX XXX XXX XXXXXXX XXXXXXXXXX XXXXXXXXXX. XXXX, XXX XXXXXXXX XXXXXXXX (XX XXXX XXXXX XXX XXXXXX) XXXX XXXXXXX XX XXX XXX XX XXX "XXXXXXXX XXXXXXXX - XX XXX XXXXXXX/XX XXXXXXXXXX".  XXX XXXX XX XXX XXXXXXXXX XXXX XXXX XXXX XX XXXXXXXXX XXXX XX XXXXXXX XX XXXXXX.  XXX XXXXXXX XXX XXXXXX XXXX XXX XXXXXXX XXXXXX XXXXXX XX XXX XXXXX XX XXXX XXXX, XXX XXX XXXXX XXXX XX XXXXXX XXXX XX X XXXXXXXXX.";
run;

按照建议,我使用过:

data test1;
   set test;
   str01 = prxchange('s/(.{200,}?)\b\s*/\1|/', -1, compbl(str1));
run;

但是,它不会将管道放置在长度小于或等于 200 个字符的单词边界处。它正在将管道放置在 200 上方。即,表达式正在前进(高于 200)而不是后退(在 200 之前或处)来放置管道。

请让我知道我们在正则表达式中缺少什么。

非常感谢!

【问题讨论】:

  • @stribizhev 感谢您的提示帮助!两者都给出了相同的结果,并且接近我想要的结果。最近,因为它用 | 替换了一个空格和空间。有没有办法没有空间?它也不应该给 |已经有 | 的地方。另外,您能否详细说明一下 $0 或 $1 的解决方案?我们可以进行条件搜索和替换,即仅当长度超过 200 时才进行搜索和替换?再次感谢!
  • 自从我给出答案后,我删除了评论。至于 $0 或 $1 的作用是什么?,我想我在下面的答案中已经阐明了这一点。我现在将更新我的答案。

标签: regex sas


【解决方案1】:

's/(.{20,}?\b).*/|/' 将整个字符串替换为不带换行符(因为它具有可选的.{20,}?.*)和替换字符串(\b)的 1 个单词边界。此外,您使用(...) 捕获文本,但您没有使用它。您可以使用反向引用在替换结果中“恢复”捕获的文本。

您至少需要删除.* 并在替换字符串中使用反向引用:

str02 = prxchange('s/(.{20,}?\b)/$1|/', -1, str1);
                               ^ ^^

根据需要调整限制量词 ({20,}) 中的数字。

您还可以摆脱捕获组并使用\0 作为整个匹配文本的反向引用:

str02 = prxchange('s/.{20,}?\b/\0|/', -1, str1);

更新

除了| 之外,有没有办法不给| 提供空间。

只需使用否定的look-behind(参见demo):

.{20,}?\b(?![\w|])

我们是否可以进行条件搜索和替换,即仅当长度大于200 时才进行搜索和替换?

我们可以,但它看起来很难看。建议先检查字符串长度,如果满足条件,继续替换:

if length(str1) > 200 then 
    str02 = prxchange('s/.{200,}?\b(?![\w|])/\0|/', -1, str1);

反向引用

您可以阅读有关regex back-references at regular-expressions.info 的更多信息。摘录如下:

如果您的正则表达式具有命名或编号的捕获组,那么您可以在替换文本中重新插入与这些捕获组中的任何一个匹配的文本。您的替换文本可以引用任意数量的组,甚至可以多次引用同一个组。这使得以多种不同方式重新排列正则表达式匹配的文本成为可能。

更新2

现在,您似乎还需要在| 的两侧“合并”单词(删除空格)。然后,只需使用以下正则表达式:

(.{20,}?)\b\s*

并替换为\1|

【讨论】:

  • @stribizhev 当我使用代码时 str02 = prxchange('s/.{200,}?\b(?![\w|])/\0|/', -1, str1 );我没有得到整个字符串替换'|'如所须。相反,它给出 "N=dddddd dddddd dddddd| dddddddddd ddd ddddd| dddddddd dd d ,n=,|t|:14.2.2-1" (在 t 之后有空格和一个额外的 |)而不是 N=dddddd dddddd dddddd|dddddddddd ddd ddddd|dddddddd dd d ,n=,|t:14.2.2-1.
  • 有一点是肯定的:t:14 之前的| 已经存在。如果您想摆脱它们,请先删除所有|。要解决第二个问题,请使用prxchange('s/(.{20,}?)\b\s*/\1|/', -1, str1);。结果是N=dddddd dddddd dddddd|dddddddddd ddd ddddd|dddddddd dd d ,n=,|t|:14.2.2-1。同样,您不能仅通过 1 次操作删除现有字符并添加一些新字符。
  • @stribizhev 我在一个实时场景中尝试了这个正则表达式。但是 |没有被放置在 200 个字符以上。我需要一个 | 200 个字符或一个字边界不超过 200 个长度。你能帮忙解决一下这种情况吗?
  • 试试s/.{0,20}\b/\0|/
  • @stribizhev 谢谢!我试过这个表达式,但它只给出 . “……”我用过“regxfot3 = prxchange('s/.{0,200}\b/\0|/', -1, str1);”请查看更新后的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-20
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多