Community
    • Login

    Help with search and replace regex

    Scheduled Pinned Locked Moved Help wanted · · · – – – · · ·
    7 Posts 5 Posters 582 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Mister AcerM
      Mister Acer
      last edited by

      Hello,
      I have project in Unity where I want to change some animation parameters via Notepd++. I have too many of them to do it by hand so I tried using regular expressions, but I’m new to it and got stuck. The files I want to edit are Unity .anim files, but it shouldn’t matter.

      I want to change values “inSlope:” and “outSlope:” to Infinity, but I only want to affect where the next “attribute:” value is m_IsActive. It will be better visible on the example data.

      Data before (it is trimmed to save space):

      - curve:
            serializedVersion: 2
            m_Curve:
            - serializedVersion: 3
              value: 0
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            m_RotationOrder: 4
          attribute: m_IsActive
      - curve:
            serializedVersion: 2
            m_Curve:
            - serializedVersion: 3
              value: 5
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            - serializedVersion: 3
              value: 1
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            - serializedVersion: 3
              value: 5
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            m_RotationOrder: 4
          attribute: m_Frame
      - curve:
            serializedVersion: 2
            m_Curve:
            - serializedVersion: 3
              value: 1
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            m_RotationOrder: 4
          attribute: m_IsActive
      

      Data after:

      - curve:
            serializedVersion: 2
            m_Curve:
            - serializedVersion: 3
              value: 0
              inSlope: Infinity
              outSlope: Infinity
              tangentMode: 0
            m_RotationOrder: 4
          attribute: m_IsActive
      - curve:
            serializedVersion: 2
            m_Curve:
            - serializedVersion: 3
              value: 5
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            - serializedVersion: 3
              value: 1
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            - serializedVersion: 3
              value: 5
              inSlope: 0
              outSlope: 0
              tangentMode: 0
            m_RotationOrder: 4
          attribute: m_Frame
      - curve:
            serializedVersion: 2
            m_Curve:
            - serializedVersion: 3
              value: 1
              inSlope: Infinity
              outSlope: Infinity
              tangentMode: 0
            m_RotationOrder: 4
          attribute: m_IsActive
      

      The closest expression to select I came up with is:
      Find What = (.*inSlope: .\r\n)(.*outSlope: .\r\n)(?=(.|\r\n)*attribute: m_IsActive)
      Did not come up with replace expression for it yet.
      Search Mode = REGULAR EXPRESSION
      Dot Matches Newline = NOT CHECKED

      I have tried few of my ideas, but the inSlope and outSlope before attribute: m_Frame are also selected. What I want to is replace every inSlope and outSlope, but only if next attribute is m_IsActive. I have been trying to do it on regex101, here’s my link: https://regex101.com/r/rfaRjW/1
      I feel like I am missing something fairly basic here, but I have been stuck on this for few hours already. Thanks for help!

      Terry RT PeterJonesP 2 Replies Last reply Reply Quote 1
      • Terry RT
        Terry R @Mister Acer
        last edited by Terry R

        @Mister-Acer said in Help with search and replace regex:

        I feel like I am missing something fairly basic here, but I have been stuck on this for few hours already. Thanks for help!

        What you are trying can be difficult. That’s because the regex will try to find what is in the lookahead. There is some help at hand. If you look at this post, you might be able to formulate one that suits.

        I did create one but it relies on there being exactly 2 lines between the “slope” and the m_attribute lines. It would seem from your post that might not always be the case.

        Find What:(?-s)(.+?inSlope: )(.+\R)(.+?outSlope: )(.+\R)(?=.+\R.+\R.+?attribute: m_IsActive)
        Replace With:${1}Infinity\r\n${3}Infinity\r\n

        However my solution may also help as you can see how I saved different portions of the lines to change into different groups, then only wrote back some of the groups, replacing other portions with the replacement text.

        Have a go at using the generic regex I linked to, since it would seem you are somewhat fluent in regex. Come back to our post with more questions if needed.

        Terry

        1 Reply Last reply Reply Quote 4
        • PeterJonesP
          PeterJones @Mister Acer
          last edited by

          @Mister-Acer said in Help with search and replace regex:

          I feel like I am missing something fairly basic here, but I have been stuck on this for few hours already.

          Nope, this is the exact opposite of “very basic”. It’s doable, but complicated.

          Thanks for sharing detailed before and after text, as well as the regex you tried.

          (.*inSlope: .\r\n)(.*outSlope: .\r\n)(?=(.|\r\n)*attribute: m_IsActive)

          At least one problem with this is that, because . matches newline is on, and .* is greedy, the first .* wants to match from the beginning of the file (or wherever you start your search) and the second .* wants to match until the very last outSlope that’s followed by attribute: m_IsActive.

          With your description, I would be tempted to start by trying the Replacing In a Specific Zone of Text regex that is linked in our Generic RegEx FAQ, using

          • FR: (inSlope|outSlope): .$
          • RR: $1: Infinity
          • BSR: ^- curve:
          • ESR: attribute: m_IsActive

          … which would say to search for inSlope or outSlope lines between - curve: and attribute: m_IsActive and replace them

          But I will admit that I haven’t had a chance to try it out, so there might be some issues with the fact that some -curve sections don’t have that same attribute, so I’m not sure if it might select too much.

          As an alternative:

          • FIND = ((?:in|out)Slope): \d(?s)(?=((?!attribute:).)*attribute: m_IsActive*) and replace with inSlope: Infinity
            REPLACE = $1: Infinity

          The left puts inSlope or outSlope in group#1, the right says “look ahead to find attribute: m_IsActive as long as there aren’t any other attribute: lines in between”. The replacement then uses inSlope or outSlope and replaces the digit with Infinity

          (if it might be more than one digit, change the \d to \d+. If it might be letters or digits, use \w+ instead)

          Thanks for a well-asked question. I hope one of these two works for you.

          (I see Terry came up with something, too, at about the same time.

          Mister AcerM 1 Reply Last reply Reply Quote 4
          • Alan KilbornA
            Alan Kilborn
            last edited by

            Here’s a variation for some fun:

            First, I’d suggest doing inSlope and outSlope separately; it’s only 2 operations instead of 1 after all…

            Try (for inSlope):

            Find what: (?-is)(inSlope: )(\w+)(?s)((?:.*?attribute: )(?:(m_IsActive)|\w+))
            Replace with: ${1}(?{4}Infinity:${2})${3}

            Sure, it can be simplified, probably the most obvious thing would be using lookbehinds and lookaheads to definitely simplify the replace term, but it could be a starting point for experimentation.

            1 Reply Last reply Reply Quote 4
            • Mister AcerM
              Mister Acer @PeterJones
              last edited by

              @PeterJones
              Thank you very much for help, I have tried your alternative solution and it did exactly what I wanted! I will also experiment with other solutions later to learn regex better as it was my first time trying something more complex and I see myself using it in the future.

              I thought it was fairly basic thing but now I understead it was more problematic then that. Well, there’s first time for everything, at least now I have slightly better understaning of the possibilities.

              Again, thank you all for help!

              1 Reply Last reply Reply Quote 1
              • guy038G
                guy038
                last edited by guy038

                Hello, @mister-acer, @terry-r, @peterjones @alan-kilborn and All,

                I noticed that there is ALWAYS a line value: \d+ before any line inSlope: \d+.

                Thus, if we consider any ...Slope \d+ line, which is followed, further on, by the nearest line attribute: m_IsActive ( due to a positive look-ahead ) and where any character, before attribute: m_IsActive, does not begin the string value ( due to a negative look-ahead), we also get a right solution !

                This description leads to this regex S/R :

                SEARCH (?xs-i) ( inSlope | outSlope) : \x20 \d+ (?= ( (?! value ) . )+? attribute: \x20 m_IsActive )

                REPLACE $1: Infinity


                Notes :

                • I use the Free Spacing mode (?x) for an easy reading of the search regex

                • We also use the Single Line mode (?s) as we perform a multi-lines search

                • Finally, it’s obvious that we must use the Not Insensitive mode (?-i)

                • The desired expression is the regex (inSlope|outSlope): \d+

                • The positive look-ahead is (?=((?!value).)+?attribute: m_IsActive)

                • The negative look-ahead is (?!value)

                Best Regards

                guy038

                Alan KilbornA 1 Reply Last reply Reply Quote 4
                • Alan KilbornA
                  Alan Kilborn @guy038
                  last edited by Alan Kilborn

                  It is good that a solution here helped out the OP, but as I read the problem statement, it struck me that, although sample data was provided, perhaps the larger data set doesn’t always conform to the key parts of the sample. Only the OP knows this (or could know it by looking at more of his data set). People proposing solutions wouldn’t know it, so they may “key off” of some things that aren’t true in the larger data set.

                  I guess my basic point is that OP should really look hard at his data set and make sure that the solution chosen really does what is intended for all of the data set. This is somewhat obvious, but it is easy to “grab and go” with a solution, and then find out later that you haven’t covered all cases, or worse, you’ve irretrievably corrupted your data.

                  It always seems easier to “trust” someone else’s solution is good for your problem. (Think about “code-grab-and-go” from a stackoverflow solution.) When you’re developing your own solution, you tend to look at things with a closer and more-critical eye.

                  Of course, if a problem with the data conversion is noticed down the road, OP could come back here and “complain” that the solution was deficient, to be told that the solution was adequate for the sample data and problem description.

                  1 Reply Last reply Reply Quote 2
                  • First post
                    Last post
                  The Community of users of the Notepad++ text editor.
                  Powered by NodeBB | Contributors