在SAS EG

时间:2016-07-14 13:49:06

标签: sql sas enterprise-guide

我试图根据SAS中的关键字提取回车的部分字符串,例如。

Str="started manually 23:56:22
Skipped: obtain name
Completed: verify dob
Skipped: ask again
Skipped: verify address 
Completed: verify country
Stopped manually 23:58:55"

我想根据SkippedCompleted提取部分内容。 因此,如果我要求Skipped,我会想要最终结果,包括回车:

Obtain name
Ask again
Verify address

我在想我需要循环查找跳过的每个实例。我尝试过SCAN,FIND,INDEX,SUBSTR的不同变体。

之前我已经提取了子字符串,但只有当字符串在字符/单词位置上保持一致时。 这个字符串非常大。可以使用不同的开始和结束措辞来存在任何跳过或已完成的数量。 我在SASeg工作。

4 个答案:

答案 0 :(得分:1)

这里的基本想法是使用CALL SCAN迭代字符串的单词,然后根据结果做任何你想做的事。

我在这里使用'|'作为单词分隔符,因为很难让回车进入编辑器,但如果它真的是CR,则使用'0A'x作为单词分隔符。

data have;
  Str="started manually 23:56:22|Skipped: obtain name|Completed: verify dob|Skipped: ask again|Skipped: verify address|Completed: verify country|Stopped manually 23:58:55";
  length str_els1-str_els10  $40;
  array str_els[10] $;

  _pos=0;
  _count=1;
  _length=0;

  do _count = 1 by 1 until (_pos le 0);
    call scan(str,_count,_pos,_length,'|');
    if _pos>0 then str_els[_count] = substr(str,_pos,_length);
  end;

run;

你可能想要做的不仅仅是把它放在一个数组中,但我想从这里你可以弄清楚剩下的。另一个:的扫描可能是起点。

答案 1 :(得分:0)

我不知道如何使用SAS,但有一个建议可能是:

  • "/><Data type="
  • 替换线刹
  • 使用:_
  • 替换_blank" value="!)

这会产生类似

的东西
started manually 23" value="56" value="22"/>
<Data type="Skipped" value="obtain name"/>
<Data type="Completed" value="verify dob"/>
<Data type="Skipped" value="ask again"/>
<Data type="Skipped" value="verify address "/>
<Data type="Completed" value="verify country"/>
<Data type="Stopped manually 23" value="58" value="55

将第一行替换为<root>,将最后一行替换为</root>,然后

<root>
  <Data type="Skipped" value="obtain name"/>
  <Data type="Completed" value="verify dob"/>
  <Data type="Skipped" value="ask again"/>
  <Data type="Skipped" value="verify address "/>
  <Data type="Completed" value="verify country"/>
</root>

现在使用XPath

来检索数据应该很容易
/root/Data[@type="Skipped"]

修改

由于我不知道如何在SAS中使用XPath读取XML,我正在搜索并发现: POSITION()-function in PATH-element of XML-map works in XML Mapper, but not in SAS-code

希望这会有所帮助......

答案 2 :(得分:0)

好吧,不知道你在用什么语言,但是在C#中我会使用LINQ或者将字符串拆分成数组,如

public class ToggleBehavior : Behavior<View>
{
    readonly TapGestureRecognizer tapRecognizer;

    public ToggleBehavior()
    {
        tapRecognizer = new TapGestureRecognizer
        {
            Command = new Command(() => this.IsToggled = !this.IsToggled)
        };
    }

    public static readonly BindableProperty IsToggledProperty = BindableProperty.Create<ToggleBehavior, bool>(tb => tb.IsToggled, false);

    public bool IsToggled
    {
        set { SetValue(IsToggledProperty, value); }
        get { return (bool)GetValue(IsToggledProperty); }
    }

    protected override void OnAttachedTo(View bindable)
    {
        base.OnAttachedTo(bindable);
        bindable.GestureRecognizers.Add(this.tapRecognizer);
    }

    protected override void OnDetachingFrom(View bindable)
    {
        base.OnDetachingFrom(bindable);
        bindable.GestureRecognizers.Remove(this.tapRecognizer);
    }

    protected override void OnAttachedTo(BindableObject bindable)
    {
        base.OnAttachedTo(bindable);
        this.BindingContext = bindable.BindingContext;
        bindable.BindingContextChanged += Bindable_BindingContextChanged;
    }

    protected override void OnDetachingFrom(BindableObject bindable)
    {
        base.OnDetachingFrom(bindable);
        this.BindingContext = null;
        bindable.BindingContextChanged -= Bindable_BindingContextChanged;
    }

    void Bindable_BindingContextChanged(object sender, EventArgs e)
    {
        var bobject = sender as BindableObject;

        this.BindingContext = bobject?.BindingContext;
    }
}

然后你可以遍历数组并单独找到各个单词,并在找到单​​词后返回接下来的2个索引。以下代码输出:

var myarray=str.Split(' ');

我确信Linq的答案会更加优雅......

在SQL中,不确定......

答案 3 :(得分:0)

你没有提到你是否想要这些摘录作为记录,所以这是我的简单方法:

您可以使用byte(10)来模拟线路返回。

data a(keep=record str);
    length str $200.;
    str="started manually 23:56:22" || byte(10) ||
    "Skipped: obtain name"  || byte(10) ||
    "Completed: verify dob"  || byte(10) ||
    "Skipped: ask again"    || byte(10) ||
    "Skipped: verify address"   || byte(10) ||
    "Completed: verify country"  || byte(10) ||
    "Stopped manually 23:58:55";        
    do i=1 by 1 while(scan(str,i,byte(10)) ^=' ');
    new=scan(str,i,byte(10));
    if index(new,"Skipped")>=1 or index(new,"Completed")>=1 then
        record = scan(new,-1,":");
        else
        record = '';
    if length(record)>1 then output;
    end;
run;